Merge branch 'for-v2013.04'
authorAnatolij Gustschin <agust@denx.de>
Fri, 29 Mar 2013 12:54:10 +0000 (13:54 +0100)
committerAnatolij Gustschin <agust@denx.de>
Fri, 29 Mar 2013 12:54:10 +0000 (13:54 +0100)
Conflicts:
drivers/video/Makefile

Signed-off-by: Anatolij Gustschin <agust@denx.de>
126 files changed:
.checkpatch.conf
MAINTAINERS
MAKEALL
Makefile
README
arch/arm/config.mk
arch/arm/cpu/arm1176/bcm2835/Makefile
arch/arm/cpu/arm1176/bcm2835/mbox.c [new file with mode: 0644]
arch/arm/cpu/armv7/Makefile
arch/arm/cpu/armv7/am33xx/Makefile
arch/arm/cpu/armv7/am33xx/board.c
arch/arm/cpu/armv7/am33xx/clock_am33xx.c [moved from arch/arm/cpu/armv7/am33xx/clock.c with 91% similarity]
arch/arm/cpu/armv7/am33xx/clock_ti814x.c [new file with mode: 0644]
arch/arm/cpu/armv7/am33xx/ddr.c
arch/arm/cpu/armv7/am33xx/emif4.c
arch/arm/cpu/armv7/am33xx/mem.c
arch/arm/cpu/armv7/am33xx/sys_info.c
arch/arm/cpu/armv7/cache_v7.c
arch/arm/cpu/armv7/exynos/power.c
arch/arm/cpu/armv7/omap-common/Makefile
arch/arm/cpu/armv7/omap-common/hwinit-common.c
arch/arm/cpu/armv7/omap-common/lowlevel_init.S
arch/arm/cpu/armv7/omap-common/timer.c
arch/arm/cpu/armv7/start.S
arch/arm/dts/exynos5250.dtsi
arch/arm/dts/tegra114.dtsi
arch/arm/include/asm/arch-am33xx/clock.h
arch/arm/include/asm/arch-am33xx/clocks_am33xx.h
arch/arm/include/asm/arch-am33xx/cpu.h
arch/arm/include/asm/arch-am33xx/ddr_defs.h
arch/arm/include/asm/arch-am33xx/hardware.h
arch/arm/include/asm/arch-am33xx/hardware_am33xx.h [new file with mode: 0644]
arch/arm/include/asm/arch-am33xx/hardware_ti814x.h [new file with mode: 0644]
arch/arm/include/asm/arch-am33xx/mmc_host_def.h
arch/arm/include/asm/arch-am33xx/mux.h
arch/arm/include/asm/arch-am33xx/mux_am33xx.h [new file with mode: 0644]
arch/arm/include/asm/arch-am33xx/mux_ti814x.h [new file with mode: 0644]
arch/arm/include/asm/arch-am33xx/omap.h
arch/arm/include/asm/arch-am33xx/spl.h
arch/arm/include/asm/arch-am33xx/sys_proto.h
arch/arm/include/asm/arch-bcm2835/mbox.h [new file with mode: 0644]
arch/arm/include/asm/arch-bcm2835/sdhci.h [new file with mode: 0644]
arch/arm/include/asm/arch-exynos/power.h
arch/arm/include/asm/arch-exynos/spl.h
arch/arm/include/asm/arch-exynos/tmu.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra/board.h
arch/arm/include/asm/arch-tegra/tegra_slink.h [deleted file]
arch/arm/include/asm/arch-tegra/tegra_spi.h [deleted file]
arch/arm/include/asm/arch-tegra114/gp_padctrl.h
arch/arm/include/asm/arch-tegra114/tegra114_spi.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra20/tegra20_sflash.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra20/tegra20_slink.h [new file with mode: 0644]
arch/arm/include/asm/cache.h
arch/arm/include/asm/system.h
arch/arm/lib/cache-cp15.c
board/cm_t35/cm_t35.c
board/nvidia/common/board.c
board/nvidia/common/common.mk
board/nvidia/common/uart-spi-switch.c [deleted file]
board/nvidia/dalmore/dalmore.c
board/nvidia/dalmore/pinmux-config-dalmore.h
board/nvidia/dts/tegra114-dalmore.dts
board/nvidia/seaboard/seaboard.c
board/phytec/pcm051/board.c
board/raspberrypi/rpi_b/rpi_b.c
board/samsung/dts/exynos5250-smdk5250.dts
board/samsung/dts/exynos5250-snow.dts [new file with mode: 0644]
board/samsung/smdk5250/smdk5250.c
board/ti/am335x/board.c
board/ti/ti814x/Makefile [new file with mode: 0644]
board/ti/ti814x/evm.c [new file with mode: 0644]
board/ti/ti814x/evm.h [new file with mode: 0644]
board/ti/ti814x/mux.c [new file with mode: 0644]
boards.cfg
common/cmd_bootm.c
common/cmd_dtt.c
common/cmd_ext4.c
common/env_callback.c
common/image.c
common/lcd.c
doc/device-tree-bindings/exynos/tmu.txt [new file with mode: 0644]
drivers/mmc/Makefile
drivers/mmc/bcm2835_sdhci.c [new file with mode: 0644]
drivers/mmc/mmc.c
drivers/mmc/omap_hsmmc.c
drivers/mmc/sdhci.c
drivers/mtd/nand/omap_gpmc.c
drivers/mtd/spi/winbond.c
drivers/net/cpsw.c
drivers/power/Makefile
drivers/power/exynos-tmu.c [new file with mode: 0644]
drivers/serial/ns16550.c
drivers/sound/Makefile
drivers/sound/max98095.c [new file with mode: 0644]
drivers/sound/max98095.h [new file with mode: 0644]
drivers/sound/sound.c
drivers/spi/Makefile
drivers/spi/fdt_spi.c [new file with mode: 0644]
drivers/spi/tegra114_spi.c [new file with mode: 0644]
drivers/spi/tegra20_sflash.c [moved from drivers/spi/tegra_spi.c with 56% similarity]
drivers/spi/tegra20_slink.c [moved from drivers/spi/tegra_slink.c with 72% similarity]
drivers/video/Makefile
drivers/video/bcm2835.c [new file with mode: 0644]
include/config_defaults.h
include/configs/am335x_evm.h
include/configs/cardhu.h
include/configs/cm_t35.h
include/configs/dalmore.h
include/configs/exynos5250-dt.h
include/configs/igep00x0.h
include/configs/pcm051.h
include/configs/rpi_b.h
include/configs/snow.h [moved from arch/arm/include/asm/arch-tegra20/uart-spi-switch.h with 50% similarity]
include/configs/tegra-common-post.h
include/configs/tegra20-common.h
include/configs/ti814x_evm.h [new file with mode: 0644]
include/configs/trimslice.h
include/env_callback.h
include/fdtdec.h
include/image.h
include/power/max77686_pmic.h
include/sound.h
include/tmu.h [new file with mode: 0644]
lib/fdtdec.c
spl/Makefile
tools/checkpatch.pl

index 38386b3..d88af57 100644 (file)
@@ -15,3 +15,6 @@
 
 # enable more tests
 --strict
+
+# Not Linux, so we don't recommend usleep_range() over udelay()
+--ignore USLEEP_RANGE
index d031c3a..1614b91 100644 (file)
@@ -688,6 +688,10 @@ Stefan Herbrechtsmeier <stefan@code.herbrechtsmeier.net>
 
        dns325          ARM926EJS (Kirkwood SoC)
 
+Lauri Hintsala <lauri.hintsala@bluegiga.com>
+
+       apx4devkit      i.MX28
+
 Vaibhav Hiremath <hvaibhav@ti.com>
 
        am3517_evm      ARM ARMV7 (AM35x SoC)
@@ -806,10 +810,6 @@ Linus Walleij <linus.walleij@linaro.org>
        integratorap    various
        integratorcp    various
 
-Veli-Pekka Peltola <veli-pekka.peltola@bluegiga.com>
-
-       apx4devkit      i.MX28
-
 Luka Perkov <luka@openwrt.org>
 
        ib62x0          ARM926EJS
@@ -833,6 +833,10 @@ Stelian Pop <stelian@popies.net>
        at91sam9263ek   ARM926EJS (AT91SAM9263 SoC)
        at91sam9rlek    ARM926EJS (AT91SAM9RL SoC)
 
+Matt Porter <mporter@ti.com>
+
+       ti814x_evm      ARM ARMV7 (TI814x Soc)
+
 Dave Purdy <david.c.purdy@gmail.com>
 
        pogo_e02        ARM926EJS (Kirkwood SoC)
@@ -910,6 +914,10 @@ Matt Sealey <matt@genesi-usa.com>
 Bo Shen <voice.shen@atmel.com>
        at91sam9x5ek            ARM926EJS (AT91SAM9G15,G25,G35,X25,X35 SoC)
 
+Rajeshwari Shinde <rajeshwari.s@samsung.com>
+
+       snow                    ARM ARMV7 (EXYNOS5250 SoC)
+
 Michal Simek <monstr@monstr.eu>
 
        zynq            ARM ARMV7 (Zynq SoC)
diff --git a/MAKEALL b/MAKEALL
index c1d8957..91fa495 100755 (executable)
--- a/MAKEALL
+++ b/MAKEALL
@@ -104,9 +104,9 @@ while true ; do
        -s|--soc)
                # echo "Option SoC: argument \`$2'"
                if [ "$opt_s" ] ; then
-                       opt_s="${opt_s%)} || \$6 == \"$2\")"
+                       opt_s="${opt_s%)} || \$6 == \"$2\" || \$6 ~ /$2/)"
                else
-                       opt_s="(\$6 == \"$2\")"
+                       opt_s="(\$6 == \"$2\" || \$6 ~ /$2/)"
                fi
                SELECTED='y'
                shift 2 ;;
index 12763ce..d60a14b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -331,7 +331,7 @@ LIBS-y += api/libapi.o
 LIBS-y += post/libpost.o
 LIBS-y += test/libtest.o
 
-ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
+ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TI814X),)
 LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
 endif
 
diff --git a/README b/README
index 7f2506a..a35ef31 100644 (file)
--- a/README
+++ b/README
@@ -485,6 +485,7 @@ The following options need to be configured:
                Thumb2 this flag will result in Thumb2 code generated by
                GCC.
 
+               CONFIG_ARM_ERRATA_716044
                CONFIG_ARM_ERRATA_742230
                CONFIG_ARM_ERRATA_743622
                CONFIG_ARM_ERRATA_751472
@@ -3878,6 +3879,10 @@ Low Level (hardware related) configuration options:
                If defined, the x86 reset vector code is included. This is not
                needed when U-Boot is running from Coreboot.
 
+- CONFIG_SYS_MPUCLK
+               Defines the MPU clock speed (in MHz).
+
+               NOTE : currently only supported on AM335x platforms.
 
 Freescale QE/FMAN Firmware Support:
 -----------------------------------
index a0c89b7..e7839be 100644 (file)
@@ -24,7 +24,7 @@
 CROSS_COMPILE ?= arm-linux-
 
 ifndef CONFIG_STANDALONE_LOAD_ADDR
-ifeq ($(SOC),omap3)
+ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TI814X),)
 CONFIG_STANDALONE_LOAD_ADDR = 0x80300000
 else
 CONFIG_STANDALONE_LOAD_ADDR = 0xc100000
index 95da6a8..135de42 100644 (file)
@@ -17,7 +17,7 @@ include $(TOPDIR)/config.mk
 LIB    = $(obj)lib$(SOC).o
 
 SOBJS  := lowlevel_init.o
-COBJS  := init.o reset.o timer.o
+COBJS  := init.o reset.o timer.o mbox.o
 
 SRCS   := $(SOBJS:.o=.c) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/arch/arm/cpu/arm1176/bcm2835/mbox.c b/arch/arm/cpu/arm1176/bcm2835/mbox.c
new file mode 100644 (file)
index 0000000..fd65e33
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * (C) Copyright 2012 Stephen Warren
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/mbox.h>
+
+#define TIMEOUT (100 * 1000) /* 100mS in uS */
+
+int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv)
+{
+       struct bcm2835_mbox_regs *regs =
+               (struct bcm2835_mbox_regs *)BCM2835_MBOX_PHYSADDR;
+       ulong endtime = get_timer(0) + TIMEOUT;
+       u32 val;
+
+       debug("time: %lu timeout: %lu\n", get_timer(0), endtime);
+
+       if (send & BCM2835_CHAN_MASK) {
+               printf("mbox: Illegal mbox data 0x%08x\n", send);
+               return -1;
+       }
+
+       /* Drain any stale responses */
+
+       for (;;) {
+               val = readl(&regs->status);
+               if (val & BCM2835_MBOX_STATUS_RD_EMPTY)
+                       break;
+               if (get_timer(0) >= endtime) {
+                       printf("mbox: Timeout draining stale responses\n");
+                       return -1;
+               }
+               val = readl(&regs->read);
+       }
+
+       /* Wait for space to send */
+
+       for (;;) {
+               val = readl(&regs->status);
+               if (!(val & BCM2835_MBOX_STATUS_WR_FULL))
+                       break;
+               if (get_timer(0) >= endtime) {
+                       printf("mbox: Timeout waiting for send space\n");
+                       return -1;
+               }
+       }
+
+       /* Send the request */
+
+       val = BCM2835_MBOX_PACK(chan, send);
+       debug("mbox: TX raw: 0x%08x\n", val);
+       writel(val, &regs->write);
+
+       /* Wait for the response */
+
+       for (;;) {
+               val = readl(&regs->status);
+               if (!(val & BCM2835_MBOX_STATUS_RD_EMPTY))
+                       break;
+               if (get_timer(0) >= endtime) {
+                       printf("mbox: Timeout waiting for response\n");
+                       return -1;
+               }
+       }
+
+       /* Read the response */
+
+       val = readl(&regs->read);
+       debug("mbox: RX raw: 0x%08x\n", val);
+
+       /* Validate the response */
+
+       if (BCM2835_MBOX_UNPACK_CHAN(val) != chan) {
+               printf("mbox: Response channel mismatch\n");
+               return -1;
+       }
+
+       *recv = BCM2835_MBOX_UNPACK_DATA(val);
+
+       return 0;
+}
+
+#ifdef DEBUG
+void dump_buf(struct bcm2835_mbox_hdr *buffer)
+{
+       u32 *p;
+       u32 words;
+       int i;
+
+       p = (u32 *)buffer;
+       words = buffer->buf_size / 4;
+       for (i = 0; i < words; i++)
+               printf("    0x%04x: 0x%08x\n", i * 4, p[i]);
+}
+#endif
+
+int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer)
+{
+       int ret;
+       u32 rbuffer;
+       struct bcm2835_mbox_tag_hdr *tag;
+       int tag_index;
+
+#ifdef DEBUG
+       printf("mbox: TX buffer\n");
+       dump_buf(buffer);
+#endif
+
+       ret = bcm2835_mbox_call_raw(chan, (u32)buffer, &rbuffer);
+       if (ret)
+               return ret;
+       if (rbuffer != (u32)buffer) {
+               printf("mbox: Response buffer mismatch\n");
+               return -1;
+       }
+
+#ifdef DEBUG
+       printf("mbox: RX buffer\n");
+       dump_buf(buffer);
+#endif
+
+       /* Validate overall response status */
+
+       if (buffer->code != BCM2835_MBOX_RESP_CODE_SUCCESS) {
+               printf("mbox: Header response code invalid\n");
+               return -1;
+       }
+
+       /* Validate each tag's response status */
+
+       tag = (void *)(buffer + 1);
+       tag_index = 0;
+       while (tag->tag) {
+               if (!(tag->val_len & BCM2835_MBOX_TAG_VAL_LEN_RESPONSE)) {
+                       printf("mbox: Tag %d missing val_len response bit\n",
+                               tag_index);
+                       return -1;
+               }
+               /*
+                * Clear the reponse bit so clients can just look right at the
+                * length field without extra processing
+                */
+               tag->val_len &= ~BCM2835_MBOX_TAG_VAL_LEN_RESPONSE;
+               tag = (void *)(((u8 *)tag) + sizeof(*tag) + tag->val_buf_size);
+               tag_index++;
+       }
+
+       return 0;
+}
index 4668b3c..7a8c2d0 100644 (file)
@@ -32,7 +32,7 @@ COBJS += cache_v7.o
 COBJS  += cpu.o
 COBJS  += syslib.o
 
-ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6),)
+ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI814X),)
 SOBJS  += lowlevel_init.o
 endif
 
index 70c443e..c97e30d 100644 (file)
@@ -16,7 +16,8 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(SOC).o
 
-COBJS  += clock.o
+COBJS-$(CONFIG_AM33XX) += clock_am33xx.o
+COBJS-$(CONFIG_TI814X) += clock_ti814x.o
 COBJS  += sys_info.o
 COBJS  += mem.o
 COBJS  += ddr.o
index e35a3e3..885fb2d 100644 (file)
@@ -141,11 +141,11 @@ int arch_misc_init(void)
 {
 #ifdef CONFIG_AM335X_USB0
        musb_register(&otg0_plat, &otg0_board_data,
-               (void *)AM335X_USB0_OTG_BASE);
+               (void *)USB0_OTG_BASE);
 #endif
 #ifdef CONFIG_AM335X_USB1
        musb_register(&otg1_plat, &otg1_board_data,
-               (void *)AM335X_USB1_OTG_BASE);
+               (void *)USB1_OTG_BASE);
 #endif
        return 0;
 }
similarity index 91%
rename from arch/arm/cpu/armv7/am33xx/clock.c
rename to arch/arm/cpu/armv7/am33xx/clock_am33xx.c
index d7d98d1..afc0d92 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * clock.c
+ * clock_am33xx.c
  *
  * clocks for AM33XX based boards
  *
- * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
 #define CPGMAC0_IDLE           0x30000
 #define DPLL_CLKDCOLDO_GATE_CTRL        0x300
 
+#define OSC    (V_OSCK/1000000)
+
+#define MPUPLL_M       CONFIG_SYS_MPUCLK
+#define MPUPLL_N       (OSC-1)
+#define MPUPLL_M2      1
+
+/* Core PLL Fdll = 1 GHZ, */
+#define COREPLL_M      1000
+#define COREPLL_N      (OSC-1)
+
+#define COREPLL_M4     10      /* CORE_CLKOUTM4 = 200 MHZ */
+#define COREPLL_M5     8       /* CORE_CLKOUTM5 = 250 MHZ */
+#define COREPLL_M6     4       /* CORE_CLKOUTM6 = 500 MHZ */
+
+/*
+ * USB PHY clock is 960 MHZ. Since, this comes directly from Fdll, Fdll
+ * frequency needs to be set to 960 MHZ. Hence,
+ * For clkout = 192 MHZ, Fdll = 960 MHZ, divider values are given below
+ */
+#define PERPLL_M       960
+#define PERPLL_N       (OSC-1)
+#define PERPLL_M2      5
+
+/* DDR Freq is 266 MHZ for now */
+/* Set Fdll = 400 MHZ , Fdll = M * 2 * CLKINP/ N + 1; clkout = Fdll /(2 * M2) */
+#define DDRPLL_M       266
+#define DDRPLL_N       (OSC-1)
+#define DDRPLL_M2      1
+
 const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
 const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
 const struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL;
diff --git a/arch/arm/cpu/armv7/am33xx/clock_ti814x.c b/arch/arm/cpu/armv7/am33xx/clock_ti814x.c
new file mode 100644 (file)
index 0000000..cb4210f
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * clock_ti814x.c
+ *
+ * Clocks for TI814X based boards
+ *
+ * Copyright (C) 2013, Texas Instruments, Incorporated
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+/* PRCM */
+#define PRCM_MOD_EN            0x2
+
+/* CLK_SRC */
+#define OSC_SRC0               0
+#define OSC_SRC1               1
+
+#define L3_OSC_SRC             OSC_SRC0
+
+#define OSC_0_FREQ             20
+
+#define DCO_HS2_MIN            500
+#define DCO_HS2_MAX            1000
+#define DCO_HS1_MIN            1000
+#define DCO_HS1_MAX            2000
+
+#define SELFREQDCO_HS2         0x00000801
+#define SELFREQDCO_HS1         0x00001001
+
+#define MPU_N                  0x1
+#define MPU_M                  0x3C
+#define MPU_M2                 1
+#define MPU_CLKCTRL            0x1
+
+#define L3_N                   19
+#define L3_M                   880
+#define L3_M2                  4
+#define L3_CLKCTRL             0x801
+
+#define DDR_N                  19
+#define DDR_M                  666
+#define DDR_M2                 2
+#define DDR_CLKCTRL            0x801
+
+/* ADPLLJ register values */
+#define ADPLLJ_CLKCTRL_HS2     0x00000801 /* HS2 mode, TINT2 = 1 */
+#define ADPLLJ_CLKCTRL_HS1     0x00001001 /* HS1 mode, TINT2 = 1 */
+#define ADPLLJ_CLKCTRL_CLKDCOLDOEN     (1 << 29)
+#define ADPLLJ_CLKCTRL_IDLE            (1 << 23)
+#define ADPLLJ_CLKCTRL_CLKOUTEN                (1 << 20)
+#define ADPLLJ_CLKCTRL_CLKOUTLDOEN     (1 << 19)
+#define ADPLLJ_CLKCTRL_CLKDCOLDOPWDNZ  (1 << 17)
+#define ADPLLJ_CLKCTRL_LPMODE          (1 << 12)
+#define ADPLLJ_CLKCTRL_DRIFTGUARDIAN   (1 << 11)
+#define ADPLLJ_CLKCTRL_REGM4XEN                (1 << 10)
+#define ADPLLJ_CLKCTRL_TINITZ          (1 << 0)
+#define ADPLLJ_CLKCTRL_CLKDCO          (ADPLLJ_CLKCTRL_CLKDCOLDOEN | \
+                                        ADPLLJ_CLKCTRL_CLKOUTEN | \
+                                        ADPLLJ_CLKCTRL_CLKOUTLDOEN | \
+                                        ADPLLJ_CLKCTRL_CLKDCOLDOPWDNZ)
+
+#define ADPLLJ_STATUS_PHASELOCK                (1 << 10)
+#define ADPLLJ_STATUS_FREQLOCK         (1 << 9)
+#define ADPLLJ_STATUS_PHSFRQLOCK       (ADPLLJ_STATUS_PHASELOCK | \
+                                        ADPLLJ_STATUS_FREQLOCK)
+#define ADPLLJ_STATUS_BYPASSACK                (1 << 8)
+#define ADPLLJ_STATUS_BYPASS           (1 << 0)
+#define ADPLLJ_STATUS_BYPASSANDACK     (ADPLLJ_STATUS_BYPASSACK | \
+                                        ADPLLJ_STATUS_BYPASS)
+
+#define ADPLLJ_TENABLE_ENB             (1 << 0)
+#define ADPLLJ_TENABLEDIV_ENB          (1 << 0)
+
+#define ADPLLJ_M2NDIV_M2SHIFT          16
+
+#define MPU_PLL_BASE                   (PLL_SUBSYS_BASE + 0x048)
+#define L3_PLL_BASE                    (PLL_SUBSYS_BASE + 0x110)
+#define DDR_PLL_BASE                   (PLL_SUBSYS_BASE + 0x290)
+
+struct ad_pll {
+       unsigned int pwrctrl;
+       unsigned int clkctrl;
+       unsigned int tenable;
+       unsigned int tenablediv;
+       unsigned int m2ndiv;
+       unsigned int mn2div;
+       unsigned int fracdiv;
+       unsigned int bwctrl;
+       unsigned int fracctrl;
+       unsigned int status;
+       unsigned int m3div;
+       unsigned int rampctrl;
+};
+
+#define OSC_SRC_CTRL                   (PLL_SUBSYS_BASE + 0x2C0)
+
+/* PRCM */
+#define CM_DEFAULT_BASE                        (PRCM_BASE + 0x0500)
+
+struct cm_def {
+       unsigned int resv0[2];
+       unsigned int l3fastclkstctrl;
+       unsigned int resv1[1];
+       unsigned int pciclkstctrl;
+       unsigned int resv2[1];
+       unsigned int ducaticlkstctrl;
+       unsigned int resv3[1];
+       unsigned int emif0clkctrl;
+       unsigned int emif1clkctrl;
+       unsigned int dmmclkctrl;
+       unsigned int fwclkctrl;
+       unsigned int resv4[10];
+       unsigned int usbclkctrl;
+       unsigned int resv5[1];
+       unsigned int sataclkctrl;
+       unsigned int resv6[4];
+       unsigned int ducaticlkctrl;
+       unsigned int pciclkctrl;
+};
+
+#define CM_ALWON_BASE                  (PRCM_BASE + 0x1400)
+
+struct cm_alwon {
+       unsigned int l3slowclkstctrl;
+       unsigned int ethclkstctrl;
+       unsigned int l3medclkstctrl;
+       unsigned int mmu_clkstctrl;
+       unsigned int mmucfg_clkstctrl;
+       unsigned int ocmc0clkstctrl;
+       unsigned int vcpclkstctrl;
+       unsigned int mpuclkstctrl;
+       unsigned int sysclk4clkstctrl;
+       unsigned int sysclk5clkstctrl;
+       unsigned int sysclk6clkstctrl;
+       unsigned int rtcclkstctrl;
+       unsigned int l3fastclkstctrl;
+       unsigned int resv0[67];
+       unsigned int mcasp0clkctrl;
+       unsigned int mcasp1clkctrl;
+       unsigned int mcasp2clkctrl;
+       unsigned int mcbspclkctrl;
+       unsigned int uart0clkctrl;
+       unsigned int uart1clkctrl;
+       unsigned int uart2clkctrl;
+       unsigned int gpio0clkctrl;
+       unsigned int gpio1clkctrl;
+       unsigned int i2c0clkctrl;
+       unsigned int i2c1clkctrl;
+       unsigned int mcasp345clkctrl;
+       unsigned int atlclkctrl;
+       unsigned int mlbclkctrl;
+       unsigned int pataclkctrl;
+       unsigned int resv1[1];
+       unsigned int uart3clkctrl;
+       unsigned int uart4clkctrl;
+       unsigned int uart5clkctrl;
+       unsigned int wdtimerclkctrl;
+       unsigned int spiclkctrl;
+       unsigned int mailboxclkctrl;
+       unsigned int spinboxclkctrl;
+       unsigned int mmudataclkctrl;
+       unsigned int resv2[2];
+       unsigned int mmucfgclkctrl;
+       unsigned int resv3[2];
+       unsigned int ocmc0clkctrl;
+       unsigned int vcpclkctrl;
+       unsigned int resv4[2];
+       unsigned int controlclkctrl;
+       unsigned int resv5[2];
+       unsigned int gpmcclkctrl;
+       unsigned int ethernet0clkctrl;
+       unsigned int resv6[1];
+       unsigned int mpuclkctrl;
+       unsigned int debugssclkctrl;
+       unsigned int l3clkctrl;
+       unsigned int l4hsclkctrl;
+       unsigned int l4lsclkctrl;
+       unsigned int rtcclkctrl;
+       unsigned int tpccclkctrl;
+       unsigned int tptc0clkctrl;
+       unsigned int tptc1clkctrl;
+       unsigned int tptc2clkctrl;
+       unsigned int tptc3clkctrl;
+       unsigned int resv7[4];
+       unsigned int dcan01clkctrl;
+       unsigned int mmchs0clkctrl;
+       unsigned int mmchs1clkctrl;
+       unsigned int mmchs2clkctrl;
+       unsigned int custefuseclkctrl;
+};
+
+
+const struct cm_alwon *cmalwon = (struct cm_alwon *)CM_ALWON_BASE;
+const struct cm_def *cmdef = (struct cm_def *)CM_DEFAULT_BASE;
+
+/*
+ * Enable the peripheral clock for required peripherals
+ */
+static void enable_per_clocks(void)
+{
+       /* UART0 */
+       writel(PRCM_MOD_EN, &cmalwon->uart0clkctrl);
+       while (readl(&cmalwon->uart0clkctrl) != PRCM_MOD_EN)
+               ;
+
+       /* HSMMC1 */
+       writel(PRCM_MOD_EN, &cmalwon->mmchs1clkctrl);
+       while (readl(&cmalwon->mmchs1clkctrl) != PRCM_MOD_EN)
+               ;
+}
+
+/*
+ * select the HS1 or HS2 for DCO Freq
+ * return : CLKCTRL
+ */
+static u32 pll_dco_freq_sel(u32 clkout_dco)
+{
+       if (clkout_dco >= DCO_HS2_MIN && clkout_dco < DCO_HS2_MAX)
+               return SELFREQDCO_HS2;
+       else if (clkout_dco >= DCO_HS1_MIN && clkout_dco < DCO_HS1_MAX)
+               return SELFREQDCO_HS1;
+       else
+               return -1;
+}
+
+/*
+ * select the sigma delta config
+ * return: sigma delta val
+ */
+static u32 pll_sigma_delta_val(u32 clkout_dco)
+{
+       u32 sig_val = 0;
+       float frac_div;
+
+       frac_div = (float) clkout_dco / 250;
+       frac_div = frac_div + 0.90;
+       sig_val = (int)frac_div;
+       sig_val = sig_val << 24;
+
+       return sig_val;
+}
+
+/*
+ * configure individual ADPLLJ
+ */
+static void pll_config(u32 base, u32 n, u32 m, u32 m2,
+                      u32 clkctrl_val, int adpllj)
+{
+       const struct ad_pll *adpll = (struct ad_pll *)base;
+       u32 m2nval, mn2val, read_clkctrl = 0, clkout_dco = 0;
+       u32 sig_val = 0, hs_mod = 0;
+
+       m2nval = (m2 << ADPLLJ_M2NDIV_M2SHIFT) | n;
+       mn2val = m;
+
+       /* calculate clkout_dco */
+       clkout_dco = ((OSC_0_FREQ / (n+1)) * m);
+
+       /* sigma delta & Hs mode selection skip for ADPLLS*/
+       if (adpllj) {
+               sig_val = pll_sigma_delta_val(clkout_dco);
+               hs_mod = pll_dco_freq_sel(clkout_dco);
+       }
+
+       /* by-pass pll */
+       read_clkctrl = readl(&adpll->clkctrl);
+       writel((read_clkctrl | ADPLLJ_CLKCTRL_IDLE), &adpll->clkctrl);
+       while ((readl(&adpll->status) & ADPLLJ_STATUS_BYPASSANDACK)
+               != ADPLLJ_STATUS_BYPASSANDACK)
+               ;
+
+       /* clear TINITZ */
+       read_clkctrl = readl(&adpll->clkctrl);
+       writel((read_clkctrl & ~ADPLLJ_CLKCTRL_TINITZ), &adpll->clkctrl);
+
+       /*
+        * ref_clk = 20/(n + 1);
+        * clkout_dco = ref_clk * m;
+        * clk_out = clkout_dco/m2;
+       */
+       read_clkctrl = readl(&adpll->clkctrl) &
+                            ~(ADPLLJ_CLKCTRL_LPMODE |
+                            ADPLLJ_CLKCTRL_DRIFTGUARDIAN |
+                            ADPLLJ_CLKCTRL_REGM4XEN);
+       writel(m2nval, &adpll->m2ndiv);
+       writel(mn2val, &adpll->mn2div);
+
+       /* Skip for modena(ADPLLS) */
+       if (adpllj) {
+               writel(sig_val, &adpll->fracdiv);
+               writel((read_clkctrl | hs_mod), &adpll->clkctrl);
+       }
+
+       /* Load M2, N2 dividers of ADPLL */
+       writel(ADPLLJ_TENABLEDIV_ENB, &adpll->tenablediv);
+       writel(~ADPLLJ_TENABLEDIV_ENB, &adpll->tenablediv);
+
+       /* Load M, N dividers of ADPLL */
+       writel(ADPLLJ_TENABLE_ENB, &adpll->tenable);
+       writel(~ADPLLJ_TENABLE_ENB, &adpll->tenable);
+
+       /* Configure CLKDCOLDOEN,CLKOUTLDOEN,CLKOUT Enable BITS */
+       read_clkctrl = readl(&adpll->clkctrl) & ~ADPLLJ_CLKCTRL_CLKDCO;
+       if (adpllj)
+               writel((read_clkctrl | ADPLLJ_CLKCTRL_CLKDCO),
+                                               &adpll->clkctrl);
+
+       /* Enable TINTZ and disable IDLE(PLL in Active & Locked Mode */
+       read_clkctrl = readl(&adpll->clkctrl) & ~ADPLLJ_CLKCTRL_IDLE;
+       writel((read_clkctrl | ADPLLJ_CLKCTRL_TINITZ), &adpll->clkctrl);
+
+       /* Wait for phase and freq lock */
+       while ((readl(&adpll->status) & ADPLLJ_STATUS_PHSFRQLOCK) !=
+              ADPLLJ_STATUS_PHSFRQLOCK)
+               ;
+}
+
+static void unlock_pll_control_mmr(void)
+{
+       /* TRM 2.10.1.4 and 3.2.7-3.2.11 */
+       writel(0x1EDA4C3D, 0x481C5040);
+       writel(0x2FF1AC2B, 0x48140060);
+       writel(0xF757FDC0, 0x48140064);
+       writel(0xE2BC3A6D, 0x48140068);
+       writel(0x1EBF131D, 0x4814006c);
+       writel(0x6F361E05, 0x48140070);
+}
+
+static void mpu_pll_config(void)
+{
+       pll_config(MPU_PLL_BASE, MPU_N, MPU_M, MPU_M2, MPU_CLKCTRL, 0);
+}
+
+static void l3_pll_config(void)
+{
+       u32 l3_osc_src, rd_osc_src = 0;
+
+       l3_osc_src = L3_OSC_SRC;
+       rd_osc_src = readl(OSC_SRC_CTRL);
+
+       if (OSC_SRC0 == l3_osc_src)
+               writel((rd_osc_src & 0xfffffffe)|0x0, OSC_SRC_CTRL);
+       else
+               writel((rd_osc_src & 0xfffffffe)|0x1, OSC_SRC_CTRL);
+
+       pll_config(L3_PLL_BASE, L3_N, L3_M, L3_M2, L3_CLKCTRL, 1);
+}
+
+void ddr_pll_config(unsigned int ddrpll_m)
+{
+       pll_config(DDR_PLL_BASE, DDR_N, DDR_M, DDR_M2, DDR_CLKCTRL, 1);
+}
+
+void enable_emif_clocks(void) {};
+
+void enable_dmm_clocks(void)
+{
+       writel(PRCM_MOD_EN, &cmdef->fwclkctrl);
+       writel(PRCM_MOD_EN, &cmdef->l3fastclkstctrl);
+       writel(PRCM_MOD_EN, &cmdef->emif0clkctrl);
+       while ((readl(&cmdef->emif0clkctrl)) != PRCM_MOD_EN)
+               ;
+       writel(PRCM_MOD_EN, &cmdef->emif1clkctrl);
+       while ((readl(&cmdef->emif1clkctrl)) != PRCM_MOD_EN)
+               ;
+       while ((readl(&cmdef->l3fastclkstctrl) & 0x300) != 0x300)
+               ;
+       writel(PRCM_MOD_EN, &cmdef->dmmclkctrl);
+       while ((readl(&cmdef->dmmclkctrl)) != PRCM_MOD_EN)
+               ;
+       writel(PRCM_MOD_EN, &cmalwon->l3slowclkstctrl);
+       while ((readl(&cmalwon->l3slowclkstctrl) & 0x2100) != 0x2100)
+               ;
+}
+
+/*
+ * Configure the PLL/PRCM for necessary peripherals
+ */
+void pll_init()
+{
+       unlock_pll_control_mmr();
+
+       /* Enable the control module */
+       writel(PRCM_MOD_EN, &cmalwon->controlclkctrl);
+
+       mpu_pll_config();
+
+       l3_pll_config();
+
+       /* Enable the required peripherals */
+       enable_per_clocks();
+}
index 448cc40..d1e2fd3 100644 (file)
@@ -24,15 +24,20 @@ http://www.ti.com/
 /**
  * Base address for EMIF instances
  */
-static struct emif_reg_struct *emif_reg = {
-                               (struct emif_reg_struct *)EMIF4_0_CFG_BASE};
+static struct emif_reg_struct *emif_reg[2] = {
+                               (struct emif_reg_struct *)EMIF4_0_CFG_BASE,
+                               (struct emif_reg_struct *)EMIF4_1_CFG_BASE};
 
 /**
- * Base address for DDR instance
+ * Base addresses for DDR PHY cmd/data regs
  */
-static struct ddr_regs *ddr_reg[2] = {
-                               (struct ddr_regs *)DDR_PHY_BASE_ADDR,
-                               (struct ddr_regs *)DDR_PHY_BASE_ADDR2};
+static struct ddr_cmd_regs *ddr_cmd_reg[2] = {
+                               (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR,
+                               (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR2};
+
+static struct ddr_data_regs *ddr_data_reg[2] = {
+                               (struct ddr_data_regs *)DDR_PHY_DATA_ADDR,
+                               (struct ddr_data_regs *)DDR_PHY_DATA_ADDR2};
 
 /**
  * Base address for ddr io control instances
@@ -43,7 +48,7 @@ static struct ddr_cmdtctrl *ioctrl_reg = {
 /**
  * Configure SDRAM
  */
-void config_sdram(const struct emif_regs *regs)
+void config_sdram(const struct emif_regs *regs, int nr)
 {
        if (regs->zq_config) {
                /*
@@ -51,68 +56,85 @@ void config_sdram(const struct emif_regs *regs)
                 * about 570us for a delay, which will be long enough
                 * to configure things.
                 */
-               writel(0x2800, &emif_reg->emif_sdram_ref_ctrl);
-               writel(regs->zq_config, &emif_reg->emif_zq_config);
+               writel(0x2800, &emif_reg[nr]->emif_sdram_ref_ctrl);
+               writel(regs->zq_config, &emif_reg[nr]->emif_zq_config);
                writel(regs->sdram_config, &cstat->secure_emif_sdram_config);
+               writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
+               writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
+               writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
        }
-       writel(regs->sdram_config, &emif_reg->emif_sdram_config);
-       writel(regs->ref_ctrl, &emif_reg->emif_sdram_ref_ctrl);
-       writel(regs->ref_ctrl, &emif_reg->emif_sdram_ref_ctrl_shdw);
+       writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
+       writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
+       writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
 }
 
 /**
  * Set SDRAM timings
  */
-void set_sdram_timings(const struct emif_regs *regs)
+void set_sdram_timings(const struct emif_regs *regs, int nr)
 {
-       writel(regs->sdram_tim1, &emif_reg->emif_sdram_tim_1);
-       writel(regs->sdram_tim1, &emif_reg->emif_sdram_tim_1_shdw);
-       writel(regs->sdram_tim2, &emif_reg->emif_sdram_tim_2);
-       writel(regs->sdram_tim2, &emif_reg->emif_sdram_tim_2_shdw);
-       writel(regs->sdram_tim3, &emif_reg->emif_sdram_tim_3);
-       writel(regs->sdram_tim3, &emif_reg->emif_sdram_tim_3_shdw);
+       writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1);
+       writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1_shdw);
+       writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2);
+       writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2_shdw);
+       writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3);
+       writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3_shdw);
 }
 
 /**
  * Configure DDR PHY
  */
-void config_ddr_phy(const struct emif_regs *regs)
+void config_ddr_phy(const struct emif_regs *regs, int nr)
 {
-       writel(regs->emif_ddr_phy_ctlr_1, &emif_reg->emif_ddr_phy_ctrl_1);
-       writel(regs->emif_ddr_phy_ctlr_1, &emif_reg->emif_ddr_phy_ctrl_1_shdw);
+       writel(regs->emif_ddr_phy_ctlr_1,
+               &emif_reg[nr]->emif_ddr_phy_ctrl_1);
+       writel(regs->emif_ddr_phy_ctlr_1,
+               &emif_reg[nr]->emif_ddr_phy_ctrl_1_shdw);
 }
 
 /**
  * Configure DDR CMD control registers
  */
-void config_cmd_ctrl(const struct cmd_control *cmd)
+void config_cmd_ctrl(const struct cmd_control *cmd, int nr)
 {
-       writel(cmd->cmd0csratio, &ddr_reg[0]->cm0csratio);
-       writel(cmd->cmd0dldiff, &ddr_reg[0]->cm0dldiff);
-       writel(cmd->cmd0iclkout, &ddr_reg[0]->cm0iclkout);
+       writel(cmd->cmd0csratio, &ddr_cmd_reg[nr]->cm0csratio);
+       writel(cmd->cmd0dldiff, &ddr_cmd_reg[nr]->cm0dldiff);
+       writel(cmd->cmd0iclkout, &ddr_cmd_reg[nr]->cm0iclkout);
 
-       writel(cmd->cmd1csratio, &ddr_reg[0]->cm1csratio);
-       writel(cmd->cmd1dldiff, &ddr_reg[0]->cm1dldiff);
-       writel(cmd->cmd1iclkout, &ddr_reg[0]->cm1iclkout);
+       writel(cmd->cmd1csratio, &ddr_cmd_reg[nr]->cm1csratio);
+       writel(cmd->cmd1dldiff, &ddr_cmd_reg[nr]->cm1dldiff);
+       writel(cmd->cmd1iclkout, &ddr_cmd_reg[nr]->cm1iclkout);
 
-       writel(cmd->cmd2csratio, &ddr_reg[0]->cm2csratio);
-       writel(cmd->cmd2dldiff, &ddr_reg[0]->cm2dldiff);
-       writel(cmd->cmd2iclkout, &ddr_reg[0]->cm2iclkout);
+       writel(cmd->cmd2csratio, &ddr_cmd_reg[nr]->cm2csratio);
+       writel(cmd->cmd2dldiff, &ddr_cmd_reg[nr]->cm2dldiff);
+       writel(cmd->cmd2iclkout, &ddr_cmd_reg[nr]->cm2iclkout);
 }
 
 /**
  * Configure DDR DATA registers
  */
-void config_ddr_data(int macrono, const struct ddr_data *data)
+void config_ddr_data(const struct ddr_data *data, int nr)
 {
-       writel(data->datardsratio0, &ddr_reg[macrono]->dt0rdsratio0);
-       writel(data->datawdsratio0, &ddr_reg[macrono]->dt0wdsratio0);
-       writel(data->datawiratio0, &ddr_reg[macrono]->dt0wiratio0);
-       writel(data->datagiratio0, &ddr_reg[macrono]->dt0giratio0);
-       writel(data->datafwsratio0, &ddr_reg[macrono]->dt0fwsratio0);
-       writel(data->datawrsratio0, &ddr_reg[macrono]->dt0wrsratio0);
-       writel(data->datauserank0delay, &ddr_reg[macrono]->dt0rdelays0);
-       writel(data->datadldiff0, &ddr_reg[macrono]->dt0dldiff0);
+       int i;
+
+       for (i = 0; i < DDR_DATA_REGS_NR; i++) {
+               writel(data->datardsratio0,
+                       &(ddr_data_reg[nr]+i)->dt0rdsratio0);
+               writel(data->datawdsratio0,
+                       &(ddr_data_reg[nr]+i)->dt0wdsratio0);
+               writel(data->datawiratio0,
+                       &(ddr_data_reg[nr]+i)->dt0wiratio0);
+               writel(data->datagiratio0,
+                       &(ddr_data_reg[nr]+i)->dt0giratio0);
+               writel(data->datafwsratio0,
+                       &(ddr_data_reg[nr]+i)->dt0fwsratio0);
+               writel(data->datawrsratio0,
+                       &(ddr_data_reg[nr]+i)->dt0wrsratio0);
+               writel(data->datauserank0delay,
+                       &(ddr_data_reg[nr]+i)->dt0rdelays0);
+               writel(data->datadldiff0,
+                       &(ddr_data_reg[nr]+i)->dt0dldiff0);
+       }
 }
 
 void config_io_ctrl(unsigned long val)
index 01e3a52..aa84e96 100644 (file)
@@ -44,44 +44,65 @@ void dram_init_banksize(void)
 
 
 #ifdef CONFIG_SPL_BUILD
-static struct vtp_reg *vtpreg = (struct vtp_reg *)VTP0_CTRL_ADDR;
+static struct dmm_lisa_map_regs *hw_lisa_map_regs =
+                               (struct dmm_lisa_map_regs *)DMM_BASE;
+static struct vtp_reg *vtpreg[2] = {
+                               (struct vtp_reg *)VTP0_CTRL_ADDR,
+                               (struct vtp_reg *)VTP1_CTRL_ADDR};
+#ifdef CONFIG_AM33XX
 static struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR;
+#endif
+
+void config_dmm(const struct dmm_lisa_map_regs *regs)
+{
+       enable_dmm_clocks();
+
+       writel(0, &hw_lisa_map_regs->dmm_lisa_map_3);
+       writel(0, &hw_lisa_map_regs->dmm_lisa_map_2);
+       writel(0, &hw_lisa_map_regs->dmm_lisa_map_1);
+       writel(0, &hw_lisa_map_regs->dmm_lisa_map_0);
 
-static void config_vtp(void)
+       writel(regs->dmm_lisa_map_3, &hw_lisa_map_regs->dmm_lisa_map_3);
+       writel(regs->dmm_lisa_map_2, &hw_lisa_map_regs->dmm_lisa_map_2);
+       writel(regs->dmm_lisa_map_1, &hw_lisa_map_regs->dmm_lisa_map_1);
+       writel(regs->dmm_lisa_map_0, &hw_lisa_map_regs->dmm_lisa_map_0);
+}
+
+static void config_vtp(int nr)
 {
-       writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_ENABLE,
-                       &vtpreg->vtp0ctrlreg);
-       writel(readl(&vtpreg->vtp0ctrlreg) & (~VTP_CTRL_START_EN),
-                       &vtpreg->vtp0ctrlreg);
-       writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_START_EN,
-                       &vtpreg->vtp0ctrlreg);
+       writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_ENABLE,
+                       &vtpreg[nr]->vtp0ctrlreg);
+       writel(readl(&vtpreg[nr]->vtp0ctrlreg) & (~VTP_CTRL_START_EN),
+                       &vtpreg[nr]->vtp0ctrlreg);
+       writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_START_EN,
+                       &vtpreg[nr]->vtp0ctrlreg);
 
        /* Poll for READY */
-       while ((readl(&vtpreg->vtp0ctrlreg) & VTP_CTRL_READY) !=
+       while ((readl(&vtpreg[nr]->vtp0ctrlreg) & VTP_CTRL_READY) !=
                        VTP_CTRL_READY)
                ;
 }
 
 void config_ddr(unsigned int pll, unsigned int ioctrl,
                const struct ddr_data *data, const struct cmd_control *ctrl,
-               const struct emif_regs *regs)
+               const struct emif_regs *regs, int nr)
 {
        enable_emif_clocks();
        ddr_pll_config(pll);
-       config_vtp();
-       config_cmd_ctrl(ctrl);
-
-       config_ddr_data(0, data);
-       config_ddr_data(1, data);
+       config_vtp(nr);
+       config_cmd_ctrl(ctrl, nr);
 
+       config_ddr_data(data, nr);
+#ifdef CONFIG_AM33XX
        config_io_ctrl(ioctrl);
 
        /* Set CKE to be controlled by EMIF/DDR PHY */
        writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl);
+#endif
 
        /* Program EMIF instance */
-       config_ddr_phy(regs);
-       set_sdram_timings(regs);
-       config_sdram(regs);
+       config_ddr_phy(regs, nr);
+       set_sdram_timings(regs, nr);
+       config_sdram(regs, nr);
 }
 #endif
index b8f54ab..b86b0de 100644 (file)
@@ -83,7 +83,7 @@ void gpmc_init(void)
        /* global settings */
        writel(0x00000008, &gpmc_cfg->sysconfig);
        writel(0x00000100, &gpmc_cfg->irqstatus);
-       writel(0x00000200, &gpmc_cfg->irqenable);
+       writel(0x00000100, &gpmc_cfg->irqenable);
        writel(0x00000012, &gpmc_cfg->config);
        /*
         * Disable the GPMC0 config set by ROM code
index 507b618..5fd8b47 100644 (file)
@@ -98,6 +98,9 @@ int print_cpuinfo(void)
        case AM335X:
                cpu_s = "AM335X";
                break;
+       case TI81XX:
+               cpu_s = "TI81XX";
+               break;
        default:
                cpu_s = "Unknown cpu type";
                break;
@@ -120,7 +123,7 @@ int print_cpuinfo(void)
                sec_s = "?";
        }
 
-       printf("AM%s-%s rev %d\n",
+       printf("%s-%s rev %d\n",
                        cpu_s, sec_s, get_cpu_rev());
 
        /* TODO: Print ARM and DDR frequencies  */
index 5f6d039..8748c14 100644 (file)
@@ -340,6 +340,9 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop)
 {
 }
 
+void arm_init_domains(void)
+{
+}
 #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
 
 #ifndef CONFIG_SYS_ICACHE_OFF
index d4bce6d..6375a81 100644 (file)
@@ -95,3 +95,48 @@ void set_dp_phy_ctrl(unsigned int enable)
        if (cpu_is_exynos5())
                exynos5_dp_phy_control(enable);
 }
+
+static void exynos5_set_ps_hold_ctrl(void)
+{
+       struct exynos5_power *power =
+               (struct exynos5_power *)samsung_get_base_power();
+
+       /* Set PS-Hold high */
+       setbits_le32(&power->ps_hold_control,
+                       EXYNOS_PS_HOLD_CONTROL_DATA_HIGH);
+}
+
+void set_ps_hold_ctrl(void)
+{
+       if (cpu_is_exynos5())
+               exynos5_set_ps_hold_ctrl();
+}
+
+
+static void exynos5_set_xclkout(void)
+{
+       struct exynos5_power *power =
+               (struct exynos5_power *)samsung_get_base_power();
+
+       /* use xxti for xclk out */
+       clrsetbits_le32(&power->pmu_debug, PMU_DEBUG_CLKOUT_SEL_MASK,
+                               PMU_DEBUG_XXTI);
+}
+
+void set_xclkout(void)
+{
+       if (cpu_is_exynos5())
+               exynos5_set_xclkout();
+}
+
+/* Enables hardware tripping to power off the system when TMU fails */
+void set_hw_thermal_trip(void)
+{
+       if (cpu_is_exynos5()) {
+               struct exynos5_power *power =
+                       (struct exynos5_power *)samsung_get_base_power();
+
+               /* PS_HOLD_CONTROL register ENABLE_HW_TRIP bit*/
+               setbits_le32(&power->ps_hold_control, POWER_ENABLE_HW_TRIP);
+       }
+}
index 0efc80d..55e82ba 100644 (file)
@@ -36,7 +36,7 @@ COBJS += emif-common.o
 COBJS  += vc.o
 endif
 
-ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
+ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TI814X),)
 COBJS  += boot-common.o
 SOBJS  += lowlevel_init.o
 endif
index 05ff2e8..70d16a8 100644 (file)
 #include <asm/emif.h>
 #include <asm/omap_common.h>
 #include <linux/compiler.h>
+#include <asm/cache.h>
+#include <asm/system.h>
+
+#define ARMV7_DCACHE_WRITEBACK  0xe
+#define        ARMV7_DOMAIN_CLIENT     1
+#define ARMV7_DOMAIN_MASK      (0x3 << 0)
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -269,4 +275,33 @@ void enable_caches(void)
        /* Enable D-cache. I-cache is already enabled in start.S */
        dcache_enable();
 }
+
+void dram_bank_mmu_setup(int bank)
+{
+       bd_t *bd = gd->bd;
+       int     i;
+
+       u32 start = bd->bi_dram[bank].start >> 20;
+       u32 size = bd->bi_dram[bank].size >> 20;
+       u32 end = start + size;
+
+       debug("%s: bank: %d\n", __func__, bank);
+       for (i = start; i < end; i++)
+               set_section_dcache(i, ARMV7_DCACHE_WRITEBACK);
+
+}
+
+void arm_init_domains(void)
+{
+       u32 reg;
+
+       reg = get_dacr();
+       /*
+       * Set DOMAIN to client access so that all permissions
+       * set in pagetables are validated by the mmu.
+       */
+       reg &= ~ARMV7_DOMAIN_MASK;
+       reg |= ARMV7_DOMAIN_CLIENT;
+       set_dacr(reg);
+}
 #endif
index 3581077..b933fe8 100644 (file)
@@ -26,6 +26,7 @@
  * MA 02111-1307 USA
  */
 
+#include <config.h>
 #include <asm/arch/omap.h>
 #include <asm/arch/spl.h>
 #include <linux/linkage.h>
index 36bea5f..507f687 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <common.h>
 #include <asm/io.h>
+#include <asm/arch/cpu.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
index fa5fad1..36a4c3c 100644 (file)
@@ -254,7 +254,6 @@ ENTRY(c_runtime_cpu_setup)
 #if !defined(CONFIG_TEGRA)
        /* Set vector address in CP15 VBAR register */
        ldr     r0, =_start
-       add     r0, r0, r9
        mcr     p15, 0, r0, c12, c0, 0  @Set VBAR
 #endif /* !Tegra */
 
@@ -310,6 +309,12 @@ ENTRY(cpu_init_cp15)
 #endif
        mcr     p15, 0, r0, c1, c0, 0
 
+#ifdef CONFIG_ARM_ERRATA_716044
+       mrc     p15, 0, r0, c1, c0, 0   @ read system control register
+       orr     r0, r0, #1 << 11        @ set bit #11
+       mcr     p15, 0, r0, c1, c0, 0   @ write system control register
+#endif
+
 #ifdef CONFIG_ARM_ERRATA_742230
        mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
        orr     r0, r0, #1 << 4         @ set bit #4
index ed8c8dd..61d35a8 100644 (file)
                };
        };
 
+       tmu@10060000 {
+               compatible = "samsung,exynos-tmu";
+               reg = <0x10060000 0x10000>;
+       };
+
 };
index 701c0f9..f86d18d 100644 (file)
@@ -9,6 +9,43 @@
                #clock-cells = <1>;
        };
 
+       apbdma: dma {
+               compatible = "nvidia,tegra114-apbdma", "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma";
+               reg = <0x6000a000 0x1400>;
+               interrupts = <0 104 0x04
+                             0 105 0x04
+                             0 106 0x04
+                             0 107 0x04
+                             0 108 0x04
+                             0 109 0x04
+                             0 110 0x04
+                             0 111 0x04
+                             0 112 0x04
+                             0 113 0x04
+                             0 114 0x04
+                             0 115 0x04
+                             0 116 0x04
+                             0 117 0x04
+                             0 118 0x04
+                             0 119 0x04
+                             0 128 0x04
+                             0 129 0x04
+                             0 130 0x04
+                             0 131 0x04
+                             0 132 0x04
+                             0 133 0x04
+                             0 134 0x04
+                             0 135 0x04
+                             0 136 0x04
+                             0 137 0x04
+                             0 138 0x04
+                             0 139 0x04
+                             0 140 0x04
+                             0 141 0x04
+                             0 142 0x04
+                             0 143 0x04>;
+       };
+
        gpio: gpio {
                compatible = "nvidia,tegra114-gpio", "nvidia,tegra30-gpio";
                reg = <0x6000d000 0x1000>;
                clocks = <&tegra_car 47>;
                status = "disabled";
        };
+
+       spi@7000d400 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000d400 0x200>;
+               interrupts = <0 59 0x04>;
+               nvidia,dma-request-selector = <&apbdma 15>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+               /* PERIPH_ID_SBC1, PLLP_OUT0 */
+               clocks = <&tegra_car 41>;
+       };
+
+       spi@7000d600 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000d600 0x200>;
+               interrupts = <0 82 0x04>;
+               nvidia,dma-request-selector = <&apbdma 16>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+               /* PERIPH_ID_SBC2, PLLP_OUT0 */
+               clocks = <&tegra_car 44>;
+       };
+
+       spi@7000d800 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000d480 0x200>;
+               interrupts = <0 83 0x04>;
+               nvidia,dma-request-selector = <&apbdma 17>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+               /* PERIPH_ID_SBC3, PLLP_OUT0 */
+               clocks = <&tegra_car 46>;
+       };
+
+       spi@7000da00 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000da00 0x200>;
+               interrupts = <0 93 0x04>;
+               nvidia,dma-request-selector = <&apbdma 18>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+               /* PERIPH_ID_SBC4, PLLP_OUT0 */
+               clocks = <&tegra_car 68>;
+       };
+
+       spi@7000dc00 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000dc00 0x200>;
+               interrupts = <0 94 0x04>;
+               nvidia,dma-request-selector = <&apbdma 27>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+               /* PERIPH_ID_SBC5, PLLP_OUT0 */
+               clocks = <&tegra_car 104>;
+       };
+
+       spi@7000de00 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000de00 0x200>;
+               interrupts = <0 79 0x04>;
+               nvidia,dma-request-selector = <&apbdma 28>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+               /* PERIPH_ID_SBC6, PLLP_OUT0 */
+               clocks = <&tegra_car 105>;
+       };
+
+       sdhci@78000000 {
+               compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+               reg = <0x78000000 0x200>;
+               interrupts = <0 14 0x04>;
+               clocks = <&tegra_car 14>;
+               status = "disable";
+       };
+
+       sdhci@78000200 {
+               compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+               reg = <0x78000200 0x200>;
+               interrupts = <0 15 0x04>;
+               clocks = <&tegra_car 9>;
+               status = "disable";
+       };
+
+       sdhci@78000400 {
+               compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+               reg = <0x78000400 0x200>;
+               interrupts = <0 19 0x04>;
+               clocks = <&tegra_car 69>;
+               status = "disable";
+       };
+
+       sdhci@78000600 {
+               compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+               reg = <0x78000600 0x200>;
+               interrupts = <0 31 0x04>;
+               clocks = <&tegra_car 15>;
+               status = "disable";
+       };
 };
index 872ff82..ecb5901 100644 (file)
@@ -3,7 +3,7 @@
  *
  * clock header
  *
- * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ * Copyright (C) 2011, Texas Instruments Incorporated - http://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
index d748dd2..89b63d9 100644 (file)
@@ -3,7 +3,7 @@
  *
  * AM33xx clock define
  *
- * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
 #ifndef _CLOCKS_AM33XX_H_
 #define _CLOCKS_AM33XX_H_
 
-#define OSC    (V_OSCK/1000000)
-
-/* MAIN PLL Fdll = 550 MHZ, */
-#define MPUPLL_M       550
-#define MPUPLL_N       (OSC-1)
-#define MPUPLL_M2      1
-
-/* Core PLL Fdll = 1 GHZ, */
-#define COREPLL_M      1000
-#define COREPLL_N      (OSC-1)
-
-#define COREPLL_M4     10      /* CORE_CLKOUTM4 = 200 MHZ */
-#define COREPLL_M5     8       /* CORE_CLKOUTM5 = 250 MHZ */
-#define COREPLL_M6     4       /* CORE_CLKOUTM6 = 500 MHZ */
-
-/*
- * USB PHY clock is 960 MHZ. Since, this comes directly from Fdll, Fdll
- * frequency needs to be set to 960 MHZ. Hence,
- * For clkout = 192 MHZ, Fdll = 960 MHZ, divider values are given below
- */
-#define PERPLL_M       960
-#define PERPLL_N       (OSC-1)
-#define PERPLL_M2      5
-
-/* DDR Freq is 266 MHZ for now */
-/* Set Fdll = 400 MHZ , Fdll = M * 2 * CLKINP/ N + 1; clkout = Fdll /(2 * M2) */
-#define DDRPLL_M       266
-#define DDRPLL_N       (OSC-1)
-#define DDRPLL_M2      1
+/* MAIN PLL Fdll = 550 MHz, by default */
+#ifndef CONFIG_SYS_MPUCLK
+#define CONFIG_SYS_MPUCLK      550
+#endif
 
 extern void pll_init(void);
 extern void enable_emif_clocks(void);
+extern void enable_dmm_clocks(void);
 
 #endif /* endif _CLOCKS_AM33XX_H_ */
index 16e8a80..3d3a7c8 100644 (file)
 #define HS_DEVICE                      0x2
 #define GP_DEVICE                      0x3
 
-/* cpu-id for AM33XX family */
+/* cpu-id for AM33XX and TI81XX family */
 #define AM335X                         0xB944
-#define DEVICE_ID                      0x44E10600
+#define TI81XX                         0xB81E
+#define DEVICE_ID                      (CTRL_BASE + 0x0600)
 
 /* This gives the status of the boot mode pins on the evm */
 #define SYSBOOT_MASK                   (BIT(0) | BIT(1) | BIT(2)\
 
 /* Reset control */
 #ifdef CONFIG_AM33XX
-#define PRM_RSTCTRL                    0x44E00F00
-#define PRM_RSTST                      0x44E00F08
+#define PRM_RSTCTRL                    (PRCM_BASE + 0x0F00)
+#elif defined(CONFIG_TI814X)
+#define PRM_RSTCTRL                    (PRCM_BASE + 0x00A0)
 #endif
+#define PRM_RSTST                      (PRM_RSTCTRL + 8)
 #define PRM_RSTCTRL_RESET              0x01
 #define PRM_RSTST_WARM_RESET_MASK      0x232
 
index ae43ef8..260cc34 100644 (file)
@@ -28,6 +28,7 @@
 #define VTP_CTRL_START_EN      (0x1)
 #define PHY_DLL_LOCK_DIFF      0x0
 #define DDR_CKE_CTRL_NORMAL    0x1
+#define PHY_EN_DYN_PWRDN       (0x1 << 20)
 
 /* Micron MT47H128M16RT-25E */
 #define MT47H128M16RT25E_EMIF_READ_LATENCY     0x100005
 #define MT41J256M8HX15E_PHY_FIFO_WE            0x100
 #define MT41J256M8HX15E_IOCTRL_VALUE           0x18B
 
+/* Micron MT41K256M16HA-125E */
+#define MT41K256M16HA125E_EMIF_READ_LATENCY    0x100006
+#define MT41K256M16HA125E_EMIF_TIM1            0x0888A39B
+#define MT41K256M16HA125E_EMIF_TIM2            0x26517FDA
+#define MT41K256M16HA125E_EMIF_TIM3            0x501F84EF
+#define MT41K256M16HA125E_EMIF_SDCFG           0x61C04BB2
+#define MT41K256M16HA125E_EMIF_SDREF           0x0000093B
+#define MT41K256M16HA125E_ZQ_CFG               0x50074BE4
+#define MT41K256M16HA125E_DLL_LOCK_DIFF                0x1
+#define MT41K256M16HA125E_RATIO                        0x40
+#define MT41K256M16HA125E_INVERT_CLKOUT                0x0
+#define MT41K256M16HA125E_RD_DQS               0x3C
+#define MT41K256M16HA125E_WR_DQS               0x45
+#define MT41K256M16HA125E_PHY_WR_DATA          0x7F
+#define MT41K256M16HA125E_PHY_FIFO_WE          0x9B
+#define MT41K256M16HA125E_IOCTRL_VALUE         0x18B
+
 /* Micron MT41J512M8RH-125 on EVM v1.5 */
 #define MT41J512M8RH125_EMIF_READ_LATENCY      0x06
 #define MT41J512M8RH125_EMIF_TIM1              0x0888A39B
 #define MT41J512M8RH125_PHY_WR_DATA            0x74
 #define MT41J512M8RH125_IOCTRL_VALUE           0x18B
 
+/**
+ * Configure DMM
+ */
+void config_dmm(const struct dmm_lisa_map_regs *regs);
+
 /**
  * Configure SDRAM
  */
-void config_sdram(const struct emif_regs *regs);
+void config_sdram(const struct emif_regs *regs, int nr);
 
 /**
  * Set SDRAM timings
  */
-void set_sdram_timings(const struct emif_regs *regs);
+void set_sdram_timings(const struct emif_regs *regs, int nr);
 
 /**
  * Configure DDR PHY
  */
-void config_ddr_phy(const struct emif_regs *regs);
+void config_ddr_phy(const struct emif_regs *regs, int nr);
+
+struct ddr_cmd_regs {
+       unsigned int resv0[7];
+       unsigned int cm0csratio;        /* offset 0x01C */
+       unsigned int resv1[2];
+       unsigned int cm0dldiff;         /* offset 0x028 */
+       unsigned int cm0iclkout;        /* offset 0x02C */
+       unsigned int resv2[8];
+       unsigned int cm1csratio;        /* offset 0x050 */
+       unsigned int resv3[2];
+       unsigned int cm1dldiff;         /* offset 0x05C */
+       unsigned int cm1iclkout;        /* offset 0x060 */
+       unsigned int resv4[8];
+       unsigned int cm2csratio;        /* offset 0x084 */
+       unsigned int resv5[2];
+       unsigned int cm2dldiff;         /* offset 0x090 */
+       unsigned int cm2iclkout;        /* offset 0x094 */
+       unsigned int resv6[3];
+};
+
+struct ddr_data_regs {
+       unsigned int dt0rdsratio0;      /* offset 0x0C8 */
+       unsigned int resv1[4];
+       unsigned int dt0wdsratio0;      /* offset 0x0DC */
+       unsigned int resv2[4];
+       unsigned int dt0wiratio0;       /* offset 0x0F0 */
+       unsigned int resv3;
+       unsigned int dt0wimode0;        /* offset 0x0F8 */
+       unsigned int dt0giratio0;       /* offset 0x0FC */
+       unsigned int resv4;
+       unsigned int dt0gimode0;        /* offset 0x104 */
+       unsigned int dt0fwsratio0;      /* offset 0x108 */
+       unsigned int resv5[4];
+       unsigned int dt0dqoffset;       /* offset 0x11C */
+       unsigned int dt0wrsratio0;      /* offset 0x120 */
+       unsigned int resv6[4];
+       unsigned int dt0rdelays0;       /* offset 0x134 */
+       unsigned int dt0dldiff0;        /* offset 0x138 */
+       unsigned int resv7[12];
+};
 
 /**
  * This structure represents the DDR registers on AM33XX devices.
@@ -193,12 +256,12 @@ struct ddr_data {
 /**
  * Configure DDR CMD control registers
  */
-void config_cmd_ctrl(const struct cmd_control *cmd);
+void config_cmd_ctrl(const struct cmd_control *cmd, int nr);
 
 /**
  * Configure DDR DATA registers
  */
-void config_ddr_data(int data_macrono, const struct ddr_data *data);
+void config_ddr_data(const struct ddr_data *data, int nr);
 
 /**
  * This structure represents the DDR io control on AM33XX devices.
@@ -226,6 +289,6 @@ struct ddr_ctrl {
 
 void config_ddr(unsigned int pll, unsigned int ioctrl,
                const struct ddr_data *data, const struct cmd_control *ctrl,
-               const struct emif_regs *regs);
+               const struct emif_regs *regs, int nr);
 
 #endif  /* _DDR_DEFS_H */
index 6dd3296..5a27f9c 100644 (file)
@@ -3,7 +3,7 @@
  *
  * hardware specific header
  *
- * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
 #ifndef __AM33XX_HARDWARE_H
 #define __AM33XX_HARDWARE_H
 
+#include <config.h>
 #include <asm/arch/omap.h>
+#ifdef CONFIG_AM33XX
+#include <asm/arch/hardware_am33xx.h>
+#elif defined(CONFIG_TI814X)
+#include <asm/arch/hardware_ti814x.h>
+#endif
 
-/* Module base addresses */
-#define UART0_BASE                     0x44E09000
+/*
+ * Common hardware definitions
+ */
 
 /* DM Timer base addresses */
 #define DM_TIMER0_BASE                 0x4802C000
 /* GPIO Base address */
 #define GPIO0_BASE                     0x48032000
 #define GPIO1_BASE                     0x4804C000
-#define GPIO2_BASE                     0x481AC000
 
 /* BCH Error Location Module */
 #define ELM_BASE                       0x48080000
 
-/* Watchdog Timer */
-#define WDT_BASE                       0x44E35000
-
-/* Control Module Base Address */
-#define CTRL_BASE                      0x44E10000
-#define CTRL_DEVICE_BASE               0x44E10600
-
-/* PRCM Base Address */
-#define PRCM_BASE                      0x44E00000
-
 /* EMIF Base address */
 #define EMIF4_0_CFG_BASE               0x4C000000
 #define EMIF4_1_CFG_BASE               0x4D000000
 #define PRM_DEVICE                     0x44E00F00
 
 /* VTP Base address */
-#define VTP0_CTRL_ADDR                 0x44E10E0C
+#define VTP1_CTRL_ADDR                 0x48140E10
 
 /* DDR Base address */
 #define DDR_CTRL_ADDR                  0x44E10E04
 #define DDR_CONTROL_BASE_ADDR          0x44E11404
-#define DDR_PHY_BASE_ADDR              0x44E12000
-#define DDR_PHY_BASE_ADDR2             0x44E120A4
+#define DDR_PHY_CMD_ADDR2              0x47C0C800
+#define DDR_PHY_DATA_ADDR2             0x47C0C8C8
 
 /* UART */
 #define DEFAULT_UART_BASE              UART0_BASE
 #define GPMC_BASE                      0x50000000
 
 /* CPSW Config space */
-#define AM335X_CPSW_BASE               0x4A100000
-#define AM335X_CPSW_MDIO_BASE          0x4A101000
-
-/* RTC base address */
-#define AM335X_RTC_BASE                        0x44E3E000
+#define CPSW_BASE                      0x4A100000
 
 /* OTG */
-#define AM335X_USB0_OTG_BASE           0x47401000
-#define AM335X_USB1_OTG_BASE           0x47401800
+#define USB0_OTG_BASE                  0x47401000
+#define USB1_OTG_BASE                  0x47401800
 
 #endif /* __AM33XX_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-am33xx/hardware_am33xx.h b/arch/arm/include/asm/arch-am33xx/hardware_am33xx.h
new file mode 100644 (file)
index 0000000..fa02f19
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * hardware_am33xx.h
+ *
+ * AM33xx hardware specific header
+ *
+ * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.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.
+ */
+
+#ifndef __AM33XX_HARDWARE_AM33XX_H
+#define __AM33XX_HARDWARE_AM33XX_H
+
+/* Module base addresses */
+
+/* UART Base Address */
+#define UART0_BASE                     0x44E09000
+
+/* GPIO Base address */
+#define GPIO2_BASE                     0x481AC000
+
+/* Watchdog Timer */
+#define WDT_BASE                       0x44E35000
+
+/* Control Module Base Address */
+#define CTRL_BASE                      0x44E10000
+#define CTRL_DEVICE_BASE               0x44E10600
+
+/* PRCM Base Address */
+#define PRCM_BASE                      0x44E00000
+
+/* VTP Base address */
+#define VTP0_CTRL_ADDR                 0x44E10E0C
+
+/* DDR Base address */
+#define DDR_PHY_CMD_ADDR               0x44E12000
+#define DDR_PHY_DATA_ADDR              0x44E120C8
+#define DDR_DATA_REGS_NR               2
+
+/* CPSW Config space */
+#define CPSW_MDIO_BASE                 0x4A101000
+
+/* RTC base address */
+#define RTC_BASE                       0x44E3E000
+
+#endif /* __AM33XX_HARDWARE_AM33XX_H */
diff --git a/arch/arm/include/asm/arch-am33xx/hardware_ti814x.h b/arch/arm/include/asm/arch-am33xx/hardware_ti814x.h
new file mode 100644 (file)
index 0000000..a950ac3
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * hardware_ti814x.h
+ *
+ * TI814x hardware specific header
+ *
+ * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.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.
+ */
+
+#ifndef __AM33XX_HARDWARE_TI814X_H
+#define __AM33XX_HARDWARE_TI814X_H
+
+/* Module base addresses */
+
+/* UART Base Address */
+#define UART0_BASE                     0x48020000
+
+/* Watchdog Timer */
+#define WDT_BASE                       0x481C7000
+
+/* Control Module Base Address */
+#define CTRL_BASE                      0x48140000
+
+/* PRCM Base Address */
+#define PRCM_BASE                      0x48180000
+
+/* PLL Subsystem Base Address */
+#define PLL_SUBSYS_BASE                        0x481C5000
+
+/* VTP Base address */
+#define VTP0_CTRL_ADDR                 0x48140E0C
+
+/* DDR Base address */
+#define DDR_PHY_CMD_ADDR               0x47C0C400
+#define DDR_PHY_DATA_ADDR              0x47C0C4C8
+#define DDR_DATA_REGS_NR               4
+
+/* CPSW Config space */
+#define CPSW_MDIO_BASE                 0x4A100800
+
+/* RTC base address */
+#define RTC_BASE                       0x480C0000
+
+#endif /* __AM33XX_HARDWARE_TI814X_H */
index 33c9c83..51ba791 100644 (file)
@@ -24,4 +24,9 @@
 #define OMAP_HSMMC1_BASE               0x48060100
 #define OMAP_HSMMC2_BASE               0x481D8100
 
+#if defined(CONFIG_TI814X)
+#undef MMC_CLOCK_REFERENCE
+#define MMC_CLOCK_REFERENCE    192 /* MHz */
+#endif
+
 #endif /* MMC_HOST_DEF_H */
index 460ac1c..1c6b65f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * mux.h
  *
- * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
 #include <common.h>
 #include <asm/io.h>
 
-#define MUX_CFG(value, offset) \
-       __raw_writel(value, (CTRL_BASE + offset));
-
-/* PAD Control Fields */
-#define SLEWCTRL       (0x1 << 6)
-#define RXACTIVE       (0x1 << 5)
-#define PULLDOWN_EN    (0x0 << 4) /* Pull Down Selection */
-#define PULLUP_EN      (0x1 << 4) /* Pull Up Selection */
-#define PULLUDEN       (0x0 << 3) /* Pull up enabled */
-#define PULLUDDIS      (0x1 << 3) /* Pull up disabled */
-#define MODE(val)      val     /* used for Readability */
-
-/*
- * PAD CONTROL OFFSETS
- * Field names corresponds to the pad signal name
- */
-struct pad_signals {
-       int gpmc_ad0;
-       int gpmc_ad1;
-       int gpmc_ad2;
-       int gpmc_ad3;
-       int gpmc_ad4;
-       int gpmc_ad5;
-       int gpmc_ad6;
-       int gpmc_ad7;
-       int gpmc_ad8;
-       int gpmc_ad9;
-       int gpmc_ad10;
-       int gpmc_ad11;
-       int gpmc_ad12;
-       int gpmc_ad13;
-       int gpmc_ad14;
-       int gpmc_ad15;
-       int gpmc_a0;
-       int gpmc_a1;
-       int gpmc_a2;
-       int gpmc_a3;
-       int gpmc_a4;
-       int gpmc_a5;
-       int gpmc_a6;
-       int gpmc_a7;
-       int gpmc_a8;
-       int gpmc_a9;
-       int gpmc_a10;
-       int gpmc_a11;
-       int gpmc_wait0;
-       int gpmc_wpn;
-       int gpmc_be1n;
-       int gpmc_csn0;
-       int gpmc_csn1;
-       int gpmc_csn2;
-       int gpmc_csn3;
-       int gpmc_clk;
-       int gpmc_advn_ale;
-       int gpmc_oen_ren;
-       int gpmc_wen;
-       int gpmc_be0n_cle;
-       int lcd_data0;
-       int lcd_data1;
-       int lcd_data2;
-       int lcd_data3;
-       int lcd_data4;
-       int lcd_data5;
-       int lcd_data6;
-       int lcd_data7;
-       int lcd_data8;
-       int lcd_data9;
-       int lcd_data10;
-       int lcd_data11;
-       int lcd_data12;
-       int lcd_data13;
-       int lcd_data14;
-       int lcd_data15;
-       int lcd_vsync;
-       int lcd_hsync;
-       int lcd_pclk;
-       int lcd_ac_bias_en;
-       int mmc0_dat3;
-       int mmc0_dat2;
-       int mmc0_dat1;
-       int mmc0_dat0;
-       int mmc0_clk;
-       int mmc0_cmd;
-       int mii1_col;
-       int mii1_crs;
-       int mii1_rxerr;
-       int mii1_txen;
-       int mii1_rxdv;
-       int mii1_txd3;
-       int mii1_txd2;
-       int mii1_txd1;
-       int mii1_txd0;
-       int mii1_txclk;
-       int mii1_rxclk;
-       int mii1_rxd3;
-       int mii1_rxd2;
-       int mii1_rxd1;
-       int mii1_rxd0;
-       int rmii1_refclk;
-       int mdio_data;
-       int mdio_clk;
-       int spi0_sclk;
-       int spi0_d0;
-       int spi0_d1;
-       int spi0_cs0;
-       int spi0_cs1;
-       int ecap0_in_pwm0_out;
-       int uart0_ctsn;
-       int uart0_rtsn;
-       int uart0_rxd;
-       int uart0_txd;
-       int uart1_ctsn;
-       int uart1_rtsn;
-       int uart1_rxd;
-       int uart1_txd;
-       int i2c0_sda;
-       int i2c0_scl;
-       int mcasp0_aclkx;
-       int mcasp0_fsx;
-       int mcasp0_axr0;
-       int mcasp0_ahclkr;
-       int mcasp0_aclkr;
-       int mcasp0_fsr;
-       int mcasp0_axr1;
-       int mcasp0_ahclkx;
-       int xdma_event_intr0;
-       int xdma_event_intr1;
-       int nresetin_out;
-       int porz;
-       int nnmi;
-       int osc0_in;
-       int osc0_out;
-       int rsvd1;
-       int tms;
-       int tdi;
-       int tdo;
-       int tck;
-       int ntrst;
-       int emu0;
-       int emu1;
-       int osc1_in;
-       int osc1_out;
-       int pmic_power_en;
-       int rtc_porz;
-       int rsvd2;
-       int ext_wakeup;
-       int enz_kaldo_1p8v;
-       int usb0_dm;
-       int usb0_dp;
-       int usb0_ce;
-       int usb0_id;
-       int usb0_vbus;
-       int usb0_drvvbus;
-       int usb1_dm;
-       int usb1_dp;
-       int usb1_ce;
-       int usb1_id;
-       int usb1_vbus;
-       int usb1_drvvbus;
-       int ddr_resetn;
-       int ddr_csn0;
-       int ddr_cke;
-       int ddr_ck;
-       int ddr_nck;
-       int ddr_casn;
-       int ddr_rasn;
-       int ddr_wen;
-       int ddr_ba0;
-       int ddr_ba1;
-       int ddr_ba2;
-       int ddr_a0;
-       int ddr_a1;
-       int ddr_a2;
-       int ddr_a3;
-       int ddr_a4;
-       int ddr_a5;
-       int ddr_a6;
-       int ddr_a7;
-       int ddr_a8;
-       int ddr_a9;
-       int ddr_a10;
-       int ddr_a11;
-       int ddr_a12;
-       int ddr_a13;
-       int ddr_a14;
-       int ddr_a15;
-       int ddr_odt;
-       int ddr_d0;
-       int ddr_d1;
-       int ddr_d2;
-       int ddr_d3;
-       int ddr_d4;
-       int ddr_d5;
-       int ddr_d6;
-       int ddr_d7;
-       int ddr_d8;
-       int ddr_d9;
-       int ddr_d10;
-       int ddr_d11;
-       int ddr_d12;
-       int ddr_d13;
-       int ddr_d14;
-       int ddr_d15;
-       int ddr_dqm0;
-       int ddr_dqm1;
-       int ddr_dqs0;
-       int ddr_dqsn0;
-       int ddr_dqs1;
-       int ddr_dqsn1;
-       int ddr_vref;
-       int ddr_vtp;
-       int ddr_strben0;
-       int ddr_strben1;
-       int ain7;
-       int ain6;
-       int ain5;
-       int ain4;
-       int ain3;
-       int ain2;
-       int ain1;
-       int ain0;
-       int vrefp;
-       int vrefn;
-};
+#ifdef CONFIG_AM33XX
+#include <asm/arch/mux_am33xx.h>
+#elif defined(CONFIG_TI814X)
+#include <asm/arch/mux_ti814x.h>
+#endif
 
 struct module_pin_mux {
        short reg_offset;
-       unsigned char val;
+       unsigned int val;
 };
 
 /* Pad control register offset */
@@ -259,4 +40,4 @@ struct module_pin_mux {
  */
 void configure_module_pin_mux(struct module_pin_mux *mod_pin_mux);
 
-#endif
+#endif /* endif _MUX_H */
diff --git a/arch/arm/include/asm/arch-am33xx/mux_am33xx.h b/arch/arm/include/asm/arch-am33xx/mux_am33xx.h
new file mode 100644 (file)
index 0000000..d5cab3e
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * mux_am33xx.h
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MUX_AM33XX_H_
+#define _MUX_AM33XX_H_
+
+#include <common.h>
+#include <asm/io.h>
+
+#define MUX_CFG(value, offset) \
+       __raw_writel(value, (CTRL_BASE + offset));
+
+/* PAD Control Fields */
+#define SLEWCTRL       (0x1 << 6)
+#define RXACTIVE       (0x1 << 5)
+#define PULLDOWN_EN    (0x0 << 4) /* Pull Down Selection */
+#define PULLUP_EN      (0x1 << 4) /* Pull Up Selection */
+#define PULLUDEN       (0x0 << 3) /* Pull up enabled */
+#define PULLUDDIS      (0x1 << 3) /* Pull up disabled */
+#define MODE(val)      val     /* used for Readability */
+
+/*
+ * PAD CONTROL OFFSETS
+ * Field names corresponds to the pad signal name
+ */
+struct pad_signals {
+       int gpmc_ad0;
+       int gpmc_ad1;
+       int gpmc_ad2;
+       int gpmc_ad3;
+       int gpmc_ad4;
+       int gpmc_ad5;
+       int gpmc_ad6;
+       int gpmc_ad7;
+       int gpmc_ad8;
+       int gpmc_ad9;
+       int gpmc_ad10;
+       int gpmc_ad11;
+       int gpmc_ad12;
+       int gpmc_ad13;
+       int gpmc_ad14;
+       int gpmc_ad15;
+       int gpmc_a0;
+       int gpmc_a1;
+       int gpmc_a2;
+       int gpmc_a3;
+       int gpmc_a4;
+       int gpmc_a5;
+       int gpmc_a6;
+       int gpmc_a7;
+       int gpmc_a8;
+       int gpmc_a9;
+       int gpmc_a10;
+       int gpmc_a11;
+       int gpmc_wait0;
+       int gpmc_wpn;
+       int gpmc_be1n;
+       int gpmc_csn0;
+       int gpmc_csn1;
+       int gpmc_csn2;
+       int gpmc_csn3;
+       int gpmc_clk;
+       int gpmc_advn_ale;
+       int gpmc_oen_ren;
+       int gpmc_wen;
+       int gpmc_be0n_cle;
+       int lcd_data0;
+       int lcd_data1;
+       int lcd_data2;
+       int lcd_data3;
+       int lcd_data4;
+       int lcd_data5;
+       int lcd_data6;
+       int lcd_data7;
+       int lcd_data8;
+       int lcd_data9;
+       int lcd_data10;
+       int lcd_data11;
+       int lcd_data12;
+       int lcd_data13;
+       int lcd_data14;
+       int lcd_data15;
+       int lcd_vsync;
+       int lcd_hsync;
+       int lcd_pclk;
+       int lcd_ac_bias_en;
+       int mmc0_dat3;
+       int mmc0_dat2;
+       int mmc0_dat1;
+       int mmc0_dat0;
+       int mmc0_clk;
+       int mmc0_cmd;
+       int mii1_col;
+       int mii1_crs;
+       int mii1_rxerr;
+       int mii1_txen;
+       int mii1_rxdv;
+       int mii1_txd3;
+       int mii1_txd2;
+       int mii1_txd1;
+       int mii1_txd0;
+       int mii1_txclk;
+       int mii1_rxclk;
+       int mii1_rxd3;
+       int mii1_rxd2;
+       int mii1_rxd1;
+       int mii1_rxd0;
+       int rmii1_refclk;
+       int mdio_data;
+       int mdio_clk;
+       int spi0_sclk;
+       int spi0_d0;
+       int spi0_d1;
+       int spi0_cs0;
+       int spi0_cs1;
+       int ecap0_in_pwm0_out;
+       int uart0_ctsn;
+       int uart0_rtsn;
+       int uart0_rxd;
+       int uart0_txd;
+       int uart1_ctsn;
+       int uart1_rtsn;
+       int uart1_rxd;
+       int uart1_txd;
+       int i2c0_sda;
+       int i2c0_scl;
+       int mcasp0_aclkx;
+       int mcasp0_fsx;
+       int mcasp0_axr0;
+       int mcasp0_ahclkr;
+       int mcasp0_aclkr;
+       int mcasp0_fsr;
+       int mcasp0_axr1;
+       int mcasp0_ahclkx;
+       int xdma_event_intr0;
+       int xdma_event_intr1;
+       int nresetin_out;
+       int porz;
+       int nnmi;
+       int osc0_in;
+       int osc0_out;
+       int rsvd1;
+       int tms;
+       int tdi;
+       int tdo;
+       int tck;
+       int ntrst;
+       int emu0;
+       int emu1;
+       int osc1_in;
+       int osc1_out;
+       int pmic_power_en;
+       int rtc_porz;
+       int rsvd2;
+       int ext_wakeup;
+       int enz_kaldo_1p8v;
+       int usb0_dm;
+       int usb0_dp;
+       int usb0_ce;
+       int usb0_id;
+       int usb0_vbus;
+       int usb0_drvvbus;
+       int usb1_dm;
+       int usb1_dp;
+       int usb1_ce;
+       int usb1_id;
+       int usb1_vbus;
+       int usb1_drvvbus;
+       int ddr_resetn;
+       int ddr_csn0;
+       int ddr_cke;
+       int ddr_ck;
+       int ddr_nck;
+       int ddr_casn;
+       int ddr_rasn;
+       int ddr_wen;
+       int ddr_ba0;
+       int ddr_ba1;
+       int ddr_ba2;
+       int ddr_a0;
+       int ddr_a1;
+       int ddr_a2;
+       int ddr_a3;
+       int ddr_a4;
+       int ddr_a5;
+       int ddr_a6;
+       int ddr_a7;
+       int ddr_a8;
+       int ddr_a9;
+       int ddr_a10;
+       int ddr_a11;
+       int ddr_a12;
+       int ddr_a13;
+       int ddr_a14;
+       int ddr_a15;
+       int ddr_odt;
+       int ddr_d0;
+       int ddr_d1;
+       int ddr_d2;
+       int ddr_d3;
+       int ddr_d4;
+       int ddr_d5;
+       int ddr_d6;
+       int ddr_d7;
+       int ddr_d8;
+       int ddr_d9;
+       int ddr_d10;
+       int ddr_d11;
+       int ddr_d12;
+       int ddr_d13;
+       int ddr_d14;
+       int ddr_d15;
+       int ddr_dqm0;
+       int ddr_dqm1;
+       int ddr_dqs0;
+       int ddr_dqsn0;
+       int ddr_dqs1;
+       int ddr_dqsn1;
+       int ddr_vref;
+       int ddr_vtp;
+       int ddr_strben0;
+       int ddr_strben1;
+       int ain7;
+       int ain6;
+       int ain5;
+       int ain4;
+       int ain3;
+       int ain2;
+       int ain1;
+       int ain0;
+       int vrefp;
+       int vrefn;
+};
+
+#endif /* endif _MUX_AM33XX_H_ */
diff --git a/arch/arm/include/asm/arch-am33xx/mux_ti814x.h b/arch/arm/include/asm/arch-am33xx/mux_ti814x.h
new file mode 100644 (file)
index 0000000..a26e503
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * mux_ti814x.h
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MUX_TI814X_H_
+#define _MUX_TI814X_H_
+
+/* PAD Control Fields */
+#define PINCNTL_RSV_MSK        (0x3 << 18) /* Reserved bitmask */
+#define PULLUP_EN      (0x1 << 17) /* Pull UP Selection */
+#define PULLUDEN       (0x0 << 16) /* Pull up enabled */
+#define PULLUDDIS      (0x1 << 16) /* Pull up disabled */
+#define MODE(val)      val     /* used for Readability */
+
+#define MUX_CFG(value, offset)                         \
+{                                                      \
+       int tmp;                                        \
+       tmp = __raw_readl(CTRL_BASE + offset);          \
+       tmp &= PINCNTL_RSV_MSK;                         \
+       __raw_writel(tmp | value, (CTRL_BASE + offset));\
+}
+
+/*
+ * PAD CONTROL OFFSETS
+ * Field names corresponds to the pad signal name
+ */
+struct pad_signals {
+       int pincntl1;
+       int pincntl2;
+       int pincntl3;
+       int pincntl4;
+       int pincntl5;
+       int pincntl6;
+       int pincntl7;
+       int pincntl8;
+       int pincntl9;
+       int pincntl10;
+       int pincntl11;
+       int pincntl12;
+       int pincntl13;
+       int pincntl14;
+       int pincntl15;
+       int pincntl16;
+       int pincntl17;
+       int pincntl18;
+       int pincntl19;
+       int pincntl20;
+       int pincntl21;
+       int pincntl22;
+       int pincntl23;
+       int pincntl24;
+       int pincntl25;
+       int pincntl26;
+       int pincntl27;
+       int pincntl28;
+       int pincntl29;
+       int pincntl30;
+       int pincntl31;
+       int pincntl32;
+       int pincntl33;
+       int pincntl34;
+       int pincntl35;
+       int pincntl36;
+       int pincntl37;
+       int pincntl38;
+       int pincntl39;
+       int pincntl40;
+       int pincntl41;
+       int pincntl42;
+       int pincntl43;
+       int pincntl44;
+       int pincntl45;
+       int pincntl46;
+       int pincntl47;
+       int pincntl48;
+       int pincntl49;
+       int pincntl50;
+       int pincntl51;
+       int pincntl52;
+       int pincntl53;
+       int pincntl54;
+       int pincntl55;
+       int pincntl56;
+       int pincntl57;
+       int pincntl58;
+       int pincntl59;
+       int pincntl60;
+       int pincntl61;
+       int pincntl62;
+       int pincntl63;
+       int pincntl64;
+       int pincntl65;
+       int pincntl66;
+       int pincntl67;
+       int pincntl68;
+       int pincntl69;
+       int pincntl70;
+       int pincntl71;
+       int pincntl72;
+       int pincntl73;
+       int pincntl74;
+       int pincntl75;
+       int pincntl76;
+       int pincntl77;
+       int pincntl78;
+       int pincntl79;
+       int pincntl80;
+       int pincntl81;
+       int pincntl82;
+       int pincntl83;
+       int pincntl84;
+       int pincntl85;
+       int pincntl86;
+       int pincntl87;
+       int pincntl88;
+       int pincntl89;
+       int pincntl90;
+       int pincntl91;
+       int pincntl92;
+       int pincntl93;
+       int pincntl94;
+       int pincntl95;
+       int pincntl96;
+       int pincntl97;
+       int pincntl98;
+       int pincntl99;
+       int pincntl100;
+       int pincntl101;
+       int pincntl102;
+       int pincntl103;
+       int pincntl104;
+       int pincntl105;
+       int pincntl106;
+       int pincntl107;
+       int pincntl108;
+       int pincntl109;
+       int pincntl110;
+       int pincntl111;
+       int pincntl112;
+       int pincntl113;
+       int pincntl114;
+       int pincntl115;
+       int pincntl116;
+       int pincntl117;
+       int pincntl118;
+       int pincntl119;
+       int pincntl120;
+       int pincntl121;
+       int pincntl122;
+       int pincntl123;
+       int pincntl124;
+       int pincntl125;
+       int pincntl126;
+       int pincntl127;
+       int pincntl128;
+       int pincntl129;
+       int pincntl130;
+       int pincntl131;
+       int pincntl132;
+       int pincntl133;
+       int pincntl134;
+       int pincntl135;
+       int pincntl136;
+       int pincntl137;
+       int pincntl138;
+       int pincntl139;
+       int pincntl140;
+       int pincntl141;
+       int pincntl142;
+       int pincntl143;
+       int pincntl144;
+       int pincntl145;
+       int pincntl146;
+       int pincntl147;
+       int pincntl148;
+       int pincntl149;
+       int pincntl150;
+       int pincntl151;
+       int pincntl152;
+       int pincntl153;
+       int pincntl154;
+       int pincntl155;
+       int pincntl156;
+       int pincntl157;
+       int pincntl158;
+       int pincntl159;
+       int pincntl160;
+       int pincntl161;
+       int pincntl162;
+       int pincntl163;
+       int pincntl164;
+       int pincntl165;
+       int pincntl166;
+       int pincntl167;
+       int pincntl168;
+       int pincntl169;
+       int pincntl170;
+       int pincntl171;
+       int pincntl172;
+       int pincntl173;
+       int pincntl174;
+       int pincntl175;
+       int pincntl176;
+       int pincntl177;
+       int pincntl178;
+       int pincntl179;
+       int pincntl180;
+       int pincntl181;
+       int pincntl182;
+       int pincntl183;
+       int pincntl184;
+       int pincntl185;
+       int pincntl186;
+       int pincntl187;
+       int pincntl188;
+       int pincntl189;
+       int pincntl190;
+       int pincntl191;
+       int pincntl192;
+       int pincntl193;
+       int pincntl194;
+       int pincntl195;
+       int pincntl196;
+       int pincntl197;
+       int pincntl198;
+       int pincntl199;
+       int pincntl200;
+       int pincntl201;
+       int pincntl202;
+       int pincntl203;
+       int pincntl204;
+       int pincntl205;
+       int pincntl206;
+       int pincntl207;
+       int pincntl208;
+       int pincntl209;
+       int pincntl210;
+       int pincntl211;
+       int pincntl212;
+       int pincntl213;
+       int pincntl214;
+       int pincntl215;
+       int pincntl216;
+       int pincntl217;
+       int pincntl218;
+       int pincntl219;
+       int pincntl220;
+       int pincntl221;
+       int pincntl222;
+       int pincntl223;
+       int pincntl224;
+       int pincntl225;
+       int pincntl226;
+       int pincntl227;
+       int pincntl228;
+       int pincntl229;
+       int pincntl230;
+       int pincntl231;
+       int pincntl232;
+       int pincntl233;
+       int pincntl234;
+       int pincntl235;
+       int pincntl236;
+       int pincntl237;
+       int pincntl238;
+       int pincntl239;
+       int pincntl240;
+       int pincntl241;
+       int pincntl242;
+       int pincntl243;
+       int pincntl244;
+       int pincntl245;
+       int pincntl246;
+       int pincntl247;
+       int pincntl248;
+       int pincntl249;
+       int pincntl250;
+       int pincntl251;
+       int pincntl252;
+       int pincntl253;
+       int pincntl254;
+       int pincntl255;
+       int pincntl256;
+       int pincntl257;
+       int pincntl258;
+       int pincntl259;
+       int pincntl260;
+       int pincntl261;
+       int pincntl262;
+       int pincntl263;
+       int pincntl264;
+       int pincntl265;
+       int pincntl266;
+       int pincntl267;
+       int pincntl268;
+       int pincntl269;
+       int pincntl270;
+};
+
+#endif /* endif _MUX_TI814X_H_ */
index 850f8a5..d28f9a8 100644 (file)
  * Non-secure RAM starts at 0x40300000 for GP devices. But we keep SRAM_BASE
  * at 0x40304000(EMU base) so that our code works for both EMU and GP
  */
+#ifdef CONFIG_AM33XX
 #define NON_SECURE_SRAM_START  0x40304000
 #define NON_SECURE_SRAM_END    0x4030E000
+#elif defined(CONFIG_TI814X)
+#define NON_SECURE_SRAM_START  0x40300000
+#define NON_SECURE_SRAM_END    0x40320000
+#endif
 
 /* ROM code defines */
 /* Boot device */
index e961ce0..f60b086 100644 (file)
 
 #define BOOT_DEVICE_XIP        2
 #define BOOT_DEVICE_NAND       5
+#ifdef CONFIG_AM33XX
 #define BOOT_DEVICE_MMC1       8
 #define BOOT_DEVICE_MMC2       9       /* eMMC or daughter card */
+#elif defined(CONFIG_TI814X)
+#define BOOT_DEVICE_MMC1       9
+#define BOOT_DEVICE_MMC2       8       /* ROM only supports 2nd instance */
+#endif
 #define BOOT_DEVICE_SPI                11
 #define BOOT_DEVICE_UART       65
 #define BOOT_DEVICE_USBETH     68
index 97ab60d..0910a94 100644 (file)
@@ -34,6 +34,8 @@ void setup_clocks_for_console(void);
 void ddr_pll_config(unsigned int ddrpll_M);
 
 void sdelay(unsigned long);
+
+struct gpmc_cs;
 void gpmc_init(void);
 void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
                        u32 size);
diff --git a/arch/arm/include/asm/arch-bcm2835/mbox.h b/arch/arm/include/asm/arch-bcm2835/mbox.h
new file mode 100644 (file)
index 0000000..b07c4a0
--- /dev/null
@@ -0,0 +1,433 @@
+/*
+ * (C) Copyright 2012 Stephen Warren
+ *
+ * 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.
+ */
+
+#ifndef _BCM2835_MBOX_H
+#define _BCM2835_MBOX_H
+
+#include <linux/compiler.h>
+
+/*
+ * The BCM2835 SoC contains (at least) two CPUs; the VideoCore (a/k/a "GPU")
+ * and the ARM CPU. The ARM CPU is often thought of as the main CPU.
+ * However, the VideoCore actually controls the initial SoC boot, and hides
+ * much of the hardware behind a protocol. This protocol is transported
+ * using the SoC's mailbox hardware module.
+ *
+ * The mailbox hardware supports passing 32-bit values back and forth.
+ * Presumably by software convention of the firmware, the bottom 4 bits of the
+ * value are used to indicate a logical channel, and the upper 28 bits are the
+ * actual payload. Various channels exist using these simple raw messages. See
+ * https://github.com/raspberrypi/firmware/wiki/Mailboxes for a list. As an
+ * example, the messages on the power management channel are a bitmask of
+ * devices whose power should be enabled.
+ *
+ * The property mailbox channel passes messages that contain the (16-byte
+ * aligned) ARM physical address of a memory buffer. This buffer is passed to
+ * the VC for processing, is modified in-place by the VC, and the address then
+ * passed back to the ARM CPU as the response mailbox message to indicate
+ * request completion. The buffers have a generic and extensible format; each
+ * buffer contains a standard header, a list of "tags", and a terminating zero
+ * entry. Each tag contains an ID indicating its type, and length fields for
+ * generic parsing. With some limitations, an arbitrary set of tags may be
+ * combined together into a single message buffer. This file defines structs
+ * representing the header and many individual tag layouts and IDs.
+ */
+
+/* Raw mailbox HW */
+
+#define BCM2835_MBOX_PHYSADDR  0x2000b880
+
+struct bcm2835_mbox_regs {
+       u32 read;
+       u32 rsvd0[5];
+       u32 status;
+       u32 config;
+       u32 write;
+};
+
+#define BCM2835_MBOX_STATUS_WR_FULL    0x80000000
+#define BCM2835_MBOX_STATUS_RD_EMPTY   0x40000000
+
+/* Lower 4-bits are channel ID */
+#define BCM2835_CHAN_MASK              0xf
+#define BCM2835_MBOX_PACK(chan, data)  (((data) & (~BCM2835_CHAN_MASK)) | \
+                                        (chan & BCM2835_CHAN_MASK))
+#define BCM2835_MBOX_UNPACK_CHAN(val)  ((val) & BCM2835_CHAN_MASK)
+#define BCM2835_MBOX_UNPACK_DATA(val)  ((val) & (~BCM2835_CHAN_MASK))
+
+/* Property mailbox buffer structures */
+
+#define BCM2835_MBOX_PROP_CHAN         8
+
+/* All message buffers must start with this header */
+struct bcm2835_mbox_hdr {
+       u32 buf_size;
+       u32 code;
+};
+
+#define BCM2835_MBOX_REQ_CODE          0
+#define BCM2835_MBOX_RESP_CODE_SUCCESS 0x80000000
+
+#define BCM2835_MBOX_INIT_HDR(_m_) { \
+               memset((_m_), 0, sizeof(*(_m_))); \
+               (_m_)->hdr.buf_size = sizeof(*(_m_)); \
+               (_m_)->hdr.code = 0; \
+               (_m_)->end_tag = 0; \
+       }
+
+/*
+ * A message buffer contains a list of tags. Each tag must also start with
+ * a standardized header.
+ */
+struct bcm2835_mbox_tag_hdr {
+       u32 tag;
+       u32 val_buf_size;
+       u32 val_len;
+};
+
+#define BCM2835_MBOX_INIT_TAG(_t_, _id_) { \
+               (_t_)->tag_hdr.tag = BCM2835_MBOX_TAG_##_id_; \
+               (_t_)->tag_hdr.val_buf_size = sizeof((_t_)->body); \
+               (_t_)->tag_hdr.val_len = sizeof((_t_)->body.req); \
+       }
+
+#define BCM2835_MBOX_INIT_TAG_NO_REQ(_t_, _id_) { \
+               (_t_)->tag_hdr.tag = BCM2835_MBOX_TAG_##_id_; \
+               (_t_)->tag_hdr.val_buf_size = sizeof((_t_)->body); \
+               (_t_)->tag_hdr.val_len = 0; \
+       }
+
+/* When responding, the VC sets this bit in val_len to indicate a response */
+#define BCM2835_MBOX_TAG_VAL_LEN_RESPONSE      0x80000000
+
+/*
+ * Below we define the ID and struct for many possible tags. This header only
+ * defines individual tag structs, not entire message structs, since in
+ * general an arbitrary set of tags may be combined into a single message.
+ * Clients of the mbox API are expected to define their own overall message
+ * structures by combining the header, a set of tags, and a terminating
+ * entry. For example,
+ *
+ * struct msg {
+ *     struct bcm2835_mbox_hdr hdr;
+ *     struct bcm2835_mbox_tag_get_arm_mem get_arm_mem;
+ *     ... perhaps other tags here ...
+ *     u32 end_tag;
+ * };
+ */
+
+#define BCM2835_MBOX_TAG_GET_ARM_MEMORY                0x00010005
+
+struct bcm2835_mbox_tag_get_arm_mem {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+               } req;
+               struct {
+                       u32 mem_base;
+                       u32 mem_size;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_CLOCK_RATE        0x00030002
+
+#define BCM2835_MBOX_CLOCK_ID_EMMC     1
+#define BCM2835_MBOX_CLOCK_ID_UART     2
+#define BCM2835_MBOX_CLOCK_ID_ARM      3
+#define BCM2835_MBOX_CLOCK_ID_CORE     4
+#define BCM2835_MBOX_CLOCK_ID_V3D      5
+#define BCM2835_MBOX_CLOCK_ID_H264     6
+#define BCM2835_MBOX_CLOCK_ID_ISP      7
+#define BCM2835_MBOX_CLOCK_ID_SDRAM    8
+#define BCM2835_MBOX_CLOCK_ID_PIXEL    9
+#define BCM2835_MBOX_CLOCK_ID_PWM      10
+
+struct bcm2835_mbox_tag_get_clock_rate {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+                       u32 clock_id;
+               } req;
+               struct {
+                       u32 clock_id;
+                       u32 rate_hz;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_ALLOCATE_BUFFER       0x00040001
+
+struct bcm2835_mbox_tag_allocate_buffer {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+                       u32 alignment;
+               } req;
+               struct {
+                       u32 fb_address;
+                       u32 fb_size;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_RELEASE_BUFFER                0x00048001
+
+struct bcm2835_mbox_tag_release_buffer {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+               } req;
+               struct {
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_BLANK_SCREEN          0x00040002
+
+struct bcm2835_mbox_tag_blank_screen {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+                       /* bit 0 means on, other bots reserved */
+                       u32 state;
+               } req;
+               struct {
+                       u32 state;
+               } resp;
+       } body;
+};
+
+/* Physical means output signal */
+#define BCM2835_MBOX_TAG_GET_PHYSICAL_W_H      0x00040003
+#define BCM2835_MBOX_TAG_TEST_PHYSICAL_W_H     0x00044003
+#define BCM2835_MBOX_TAG_SET_PHYSICAL_W_H      0x00048003
+
+struct bcm2835_mbox_tag_physical_w_h {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               /* req not used for get */
+               struct {
+                       u32 width;
+                       u32 height;
+               } req;
+               struct {
+                       u32 width;
+                       u32 height;
+               } resp;
+       } body;
+};
+
+/* Virtual means display buffer */
+#define BCM2835_MBOX_TAG_GET_VIRTUAL_W_H       0x00040004
+#define BCM2835_MBOX_TAG_TEST_VIRTUAL_W_H      0x00044004
+#define BCM2835_MBOX_TAG_SET_VIRTUAL_W_H       0x00048004
+
+struct bcm2835_mbox_tag_virtual_w_h {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               /* req not used for get */
+               struct {
+                       u32 width;
+                       u32 height;
+               } req;
+               struct {
+                       u32 width;
+                       u32 height;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_DEPTH             0x00040005
+#define BCM2835_MBOX_TAG_TEST_DEPTH            0x00044005
+#define BCM2835_MBOX_TAG_SET_DEPTH             0x00048005
+
+struct bcm2835_mbox_tag_depth {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               /* req not used for get */
+               struct {
+                       u32 bpp;
+               } req;
+               struct {
+                       u32 bpp;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_PIXEL_ORDER       0x00040006
+#define BCM2835_MBOX_TAG_TEST_PIXEL_ORDER      0x00044005
+#define BCM2835_MBOX_TAG_SET_PIXEL_ORDER       0x00048006
+
+#define BCM2835_MBOX_PIXEL_ORDER_BGR           0
+#define BCM2835_MBOX_PIXEL_ORDER_RGB           1
+
+struct bcm2835_mbox_tag_pixel_order {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               /* req not used for get */
+               struct {
+                       u32 order;
+               } req;
+               struct {
+                       u32 order;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_ALPHA_MODE                0x00040007
+#define BCM2835_MBOX_TAG_TEST_ALPHA_MODE       0x00044007
+#define BCM2835_MBOX_TAG_SET_ALPHA_MODE                0x00048007
+
+#define BCM2835_MBOX_ALPHA_MODE_0_OPAQUE       0
+#define BCM2835_MBOX_ALPHA_MODE_0_TRANSPARENT  1
+#define BCM2835_MBOX_ALPHA_MODE_IGNORED                2
+
+struct bcm2835_mbox_tag_alpha_mode {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               /* req not used for get */
+               struct {
+                       u32 alpha;
+               } req;
+               struct {
+                       u32 alpha;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_PITCH             0x00040008
+
+struct bcm2835_mbox_tag_pitch {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+               } req;
+               struct {
+                       u32 pitch;
+               } resp;
+       } body;
+};
+
+/* Offset of display window within buffer */
+#define BCM2835_MBOX_TAG_GET_VIRTUAL_OFFSET    0x00040009
+#define BCM2835_MBOX_TAG_TEST_VIRTUAL_OFFSET   0x00044009
+#define BCM2835_MBOX_TAG_SET_VIRTUAL_OFFSET    0x00048009
+
+struct bcm2835_mbox_tag_virtual_offset {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               /* req not used for get */
+               struct {
+                       u32 x;
+                       u32 y;
+               } req;
+               struct {
+                       u32 x;
+                       u32 y;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_OVERSCAN          0x0004000a
+#define BCM2835_MBOX_TAG_TEST_OVERSCAN         0x0004400a
+#define BCM2835_MBOX_TAG_SET_OVERSCAN          0x0004800a
+
+struct bcm2835_mbox_tag_overscan {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               /* req not used for get */
+               struct {
+                       u32 top;
+                       u32 bottom;
+                       u32 left;
+                       u32 right;
+               } req;
+               struct {
+                       u32 top;
+                       u32 bottom;
+                       u32 left;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_PALETTE           0x0004000b
+
+struct bcm2835_mbox_tag_get_palette {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+               } req;
+               struct {
+                       u32 data[1024];
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_TEST_PALETTE          0x0004400b
+
+struct bcm2835_mbox_tag_test_palette {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+                       u32 offset;
+                       u32 num_entries;
+                       u32 data[256];
+               } req;
+               struct {
+                       u32 is_invalid;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_SET_PALETTE           0x0004800b
+
+struct bcm2835_mbox_tag_set_palette {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+                       u32 offset;
+                       u32 num_entries;
+                       u32 data[256];
+               } req;
+               struct {
+                       u32 is_invalid;
+               } resp;
+       } body;
+};
+
+/*
+ * Pass a raw u32 message to the VC, and receive a raw u32 back.
+ *
+ * Returns 0 for success, any other value for error.
+ */
+int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv);
+
+/*
+ * Pass a complete property-style buffer to the VC, and wait until it has
+ * been processed.
+ *
+ * This function expects a pointer to the mbox_hdr structure in an attempt
+ * to ensure some degree of type safety. However, some number of tags and
+ * a termination value are expected to immediately follow the header in
+ * memory, as required by the property protocol.
+ *
+ * Returns 0 for success, any other value for error.
+ */
+int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer);
+
+#endif
diff --git a/arch/arm/include/asm/arch-bcm2835/sdhci.h b/arch/arm/include/asm/arch-bcm2835/sdhci.h
new file mode 100644 (file)
index 0000000..a4f867b
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * (C) Copyright 2012 Stephen Warren
+ *
+ * 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
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _BCM2835_SDHCI_H_
+#define _BCM2835_SDHCI_H_
+
+#define BCM2835_SDHCI_BASE 0x20300000
+
+int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq);
+
+#endif
index d2fdb59..3549667 100644 (file)
@@ -857,6 +857,9 @@ void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable);
 
 void set_usbhost_phy_ctrl(unsigned int enable);
 
+/* Enables hardware tripping to power off the system when TMU fails */
+void set_hw_thermal_trip(void);
+
 #define POWER_USB_HOST_PHY_CTRL_EN             (1 << 0)
 #define POWER_USB_HOST_PHY_CTRL_DISABLE                (0 << 0)
 
@@ -864,4 +867,25 @@ void set_dp_phy_ctrl(unsigned int enable);
 
 #define EXYNOS_DP_PHY_ENABLE           (1 << 0)
 
+#define EXYNOS_PS_HOLD_CONTROL_DATA_HIGH       (1 << 8)
+#define POWER_ENABLE_HW_TRIP                   (1UL << 31)
+
+/*
+ * Set ps_hold data driving value high
+ * This enables the machine to stay powered on
+ * after the initial power-on condition goes away
+ * (e.g. power button).
+ */
+void set_ps_hold_ctrl(void);
+
+/* PMU_DEBUG bits [12:8] = 0x1000 selects XXTI clock source */
+#define PMU_DEBUG_XXTI                          0x1000
+/* Mask bit[12:8] for xxti clock selection */
+#define PMU_DEBUG_CLKOUT_SEL_MASK               0x1f00
+
+/*
+ * Pmu debug is used for xclkout, enable xclkout with
+ * source as XXTI
+ */
+void set_xclkout(void);
 #endif
index 306b41d..46b25a6 100644 (file)
@@ -78,11 +78,12 @@ struct spl_machine_param {
         */
        u32             uboot_size;
        enum boot_mode  boot_source;    /* Boot device */
-       enum mem_manuf  mem_manuf;      /* Memory Manufacturer */
        unsigned        frequency_mhz;  /* Frequency of memory in MHz */
        unsigned        arm_freq_mhz;   /* ARM Frequency in MHz */
        u32             serial_base;    /* Serial base address */
        u32             i2c_base;       /* i2c base address */
+       u32             board_rev_gpios;        /* Board revision GPIOs */
+       enum mem_manuf  mem_manuf;      /* Memory Manufacturer */
 } __attribute__((__packed__));
 #endif
 
diff --git a/arch/arm/include/asm/arch-exynos/tmu.h b/arch/arm/include/asm/arch-exynos/tmu.h
new file mode 100644 (file)
index 0000000..7e0158e
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *      http://www.samsung.com
+ * Akshay Saraswat <akshay.s@samsung.com>
+ *
+ * EXYNOS - Thermal Management Unit
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ * 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 __ASM_ARCH_TMU_H
+#define __ASM_ARCH_TMU_H
+
+struct exynos5_tmu_reg {
+       unsigned triminfo;
+       unsigned rsvd1;
+       unsigned rsvd2;
+       unsigned rsvd3;
+       unsigned rsvd4;
+       unsigned triminfo_control;
+       unsigned rsvd5;
+       unsigned rsvd6;
+       unsigned tmu_control;
+       unsigned rsvd7;
+       unsigned tmu_status;
+       unsigned sampling_internal;
+       unsigned counter_value0;
+       unsigned counter_value1;
+       unsigned rsvd8;
+       unsigned rsvd9;
+       unsigned current_temp;
+       unsigned rsvd10;
+       unsigned rsvd11;
+       unsigned rsvd12;
+       unsigned threshold_temp_rise;
+       unsigned threshold_temp_fall;
+       unsigned rsvd13;
+       unsigned rsvd14;
+       unsigned past_temp3_0;
+       unsigned past_temp7_4;
+       unsigned past_temp11_8;
+       unsigned past_temp15_12;
+       unsigned inten;
+       unsigned intstat;
+       unsigned intclear;
+       unsigned rsvd15;
+       unsigned emul_con;
+};
+#endif /* __ASM_ARCH_TMU_H */
index 3db0d93..1a66990 100644 (file)
@@ -25,8 +25,7 @@
 #define _TEGRA_BOARD_H_
 
 /* Set up pinmux to make UART usable */
-void gpio_config_uart(void);      /* CONFIG_SPI_UART_SWITCH */
-void gpio_early_init_uart(void);  /*!CONFIG_SPI_UART_SWITCH */
+void gpio_early_init_uart(void);
 
 /* Set up early UART output */
 void board_init_uart_f(void);
diff --git a/arch/arm/include/asm/arch-tegra/tegra_slink.h b/arch/arm/include/asm/arch-tegra/tegra_slink.h
deleted file mode 100644 (file)
index 74804b5..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * NVIDIA Tegra SPI-SLINK controller
- *
- * Copyright 2010-2013 NVIDIA Corporation
- *
- * This software may be used and distributed according to the
- * terms of the GNU Public License, Version 2, incorporated
- * herein by reference.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * Version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef _TEGRA_SLINK_H_
-#define _TEGRA_SLINK_H_
-
-#include <asm/types.h>
-
-struct slink_tegra {
-       u32 command;    /* SLINK_COMMAND_0 register  */
-       u32 command2;   /* SLINK_COMMAND2_0 reg */
-       u32 status;     /* SLINK_STATUS_0 register */
-       u32 reserved;   /* Reserved offset 0C */
-       u32 mas_data;   /* SLINK_MAS_DATA_0 reg */
-       u32 slav_data;  /* SLINK_SLAVE_DATA_0 reg */
-       u32 dma_ctl;    /* SLINK_DMA_CTL_0 register */
-       u32 status2;    /* SLINK_STATUS2_0 reg */
-       u32 rsvd[56];   /* 0x20 to 0xFF reserved */
-       u32 tx_fifo;    /* SLINK_TX_FIFO_0 reg off 100h */
-       u32 rsvd2[31];  /* 0x104 to 0x17F reserved */
-       u32 rx_fifo;    /* SLINK_RX_FIFO_0 reg off 180h */
-};
-
-/* COMMAND */
-#define SLINK_CMD_ENB                  (1 << 31)
-#define SLINK_CMD_GO                   (1 << 30)
-#define SLINK_CMD_M_S                  (1 << 28)
-#define SLINK_CMD_CK_SDA               (1 << 21)
-#define SLINK_CMD_CS_POL               (1 << 13)
-#define SLINK_CMD_CS_VAL               (1 << 12)
-#define SLINK_CMD_CS_SOFT              (1 << 11)
-#define SLINK_CMD_BIT_LENGTH           (1 << 4)
-#define SLINK_CMD_BIT_LENGTH_MASK      0x0000001F
-/* COMMAND2 */
-#define SLINK_CMD2_TXEN                        (1 << 30)
-#define SLINK_CMD2_RXEN                        (1 << 31)
-#define SLINK_CMD2_SS_EN               (1 << 18)
-#define SLINK_CMD2_SS_EN_SHIFT         18
-#define SLINK_CMD2_SS_EN_MASK          0x000C0000
-#define SLINK_CMD2_CS_ACTIVE_BETWEEN   (1 << 17)
-/* STATUS */
-#define SLINK_STAT_BSY                 (1 << 31)
-#define SLINK_STAT_RDY                 (1 << 30)
-#define SLINK_STAT_ERR                 (1 << 29)
-#define SLINK_STAT_RXF_FLUSH           (1 << 27)
-#define SLINK_STAT_TXF_FLUSH           (1 << 26)
-#define SLINK_STAT_RXF_OVF             (1 << 25)
-#define SLINK_STAT_TXF_UNR             (1 << 24)
-#define SLINK_STAT_RXF_EMPTY           (1 << 23)
-#define SLINK_STAT_RXF_FULL            (1 << 22)
-#define SLINK_STAT_TXF_EMPTY           (1 << 21)
-#define SLINK_STAT_TXF_FULL            (1 << 20)
-#define SLINK_STAT_TXF_OVF             (1 << 19)
-#define SLINK_STAT_RXF_UNR             (1 << 18)
-#define SLINK_STAT_CUR_BLKCNT          (1 << 15)
-/* STATUS2 */
-#define SLINK_STAT2_RXF_FULL_CNT       (1 << 16)
-#define SLINK_STAT2_TXF_FULL_CNT       (1 << 0)
-
-#define SPI_TIMEOUT            1000
-#define TEGRA_SPI_MAX_FREQ     52000000
-
-#endif /* _TEGRA_SLINK_H_ */
diff --git a/arch/arm/include/asm/arch-tegra/tegra_spi.h b/arch/arm/include/asm/arch-tegra/tegra_spi.h
deleted file mode 100644 (file)
index d53a93f..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * NVIDIA Tegra20 SPI-FLASH controller
- *
- * Copyright 2010-2012 NVIDIA Corporation
- *
- * This software may be used and distributed according to the
- * terms of the GNU Public License, Version 2, incorporated
- * herein by reference.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * Version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef _TEGRA_SPI_H_
-#define _TEGRA_SPI_H_
-
-#include <asm/types.h>
-
-struct spi_tegra {
-       u32 command;    /* SPI_COMMAND_0 register  */
-       u32 status;     /* SPI_STATUS_0 register */
-       u32 rx_cmp;     /* SPI_RX_CMP_0 register  */
-       u32 dma_ctl;    /* SPI_DMA_CTL_0 register */
-       u32 tx_fifo;    /* SPI_TX_FIFO_0 register */
-       u32 rsvd[3];    /* offsets 0x14 to 0x1F reserved */
-       u32 rx_fifo;    /* SPI_RX_FIFO_0 register */
-};
-
-#define SPI_CMD_GO                     (1 << 30)
-#define SPI_CMD_ACTIVE_SCLK_SHIFT      26
-#define SPI_CMD_ACTIVE_SCLK_MASK       (3 << SPI_CMD_ACTIVE_SCLK_SHIFT)
-#define SPI_CMD_CK_SDA                 (1 << 21)
-#define SPI_CMD_ACTIVE_SDA_SHIFT       18
-#define SPI_CMD_ACTIVE_SDA_MASK                (3 << SPI_CMD_ACTIVE_SDA_SHIFT)
-#define SPI_CMD_CS_POL                 (1 << 16)
-#define SPI_CMD_TXEN                   (1 << 15)
-#define SPI_CMD_RXEN                   (1 << 14)
-#define SPI_CMD_CS_VAL                 (1 << 13)
-#define SPI_CMD_CS_SOFT                        (1 << 12)
-#define SPI_CMD_CS_DELAY               (1 << 9)
-#define SPI_CMD_CS3_EN                 (1 << 8)
-#define SPI_CMD_CS2_EN                 (1 << 7)
-#define SPI_CMD_CS1_EN                 (1 << 6)
-#define SPI_CMD_CS0_EN                 (1 << 5)
-#define SPI_CMD_BIT_LENGTH             (1 << 4)
-#define SPI_CMD_BIT_LENGTH_MASK                0x0000001F
-
-#define SPI_STAT_BSY                   (1 << 31)
-#define SPI_STAT_RDY                   (1 << 30)
-#define SPI_STAT_RXF_FLUSH             (1 << 29)
-#define SPI_STAT_TXF_FLUSH             (1 << 28)
-#define SPI_STAT_RXF_UNR               (1 << 27)
-#define SPI_STAT_TXF_OVF               (1 << 26)
-#define SPI_STAT_RXF_EMPTY             (1 << 25)
-#define SPI_STAT_RXF_FULL              (1 << 24)
-#define SPI_STAT_TXF_EMPTY             (1 << 23)
-#define SPI_STAT_TXF_FULL              (1 << 22)
-#define SPI_STAT_SEL_TXRX_N            (1 << 16)
-#define SPI_STAT_CUR_BLKCNT            (1 << 15)
-
-#define SPI_TIMEOUT            1000
-#define TEGRA_SPI_MAX_FREQ     52000000
-
-#endif /* _TEGRA_SPI_H_ */
index 1ef1a14..41ce677 100644 (file)
@@ -74,4 +74,10 @@ struct apb_misc_gp_ctlr {
        u32     aocfg0;         /* 0x1AC: APB_MISC_GP_AOCFG0PADCTRL */
 };
 
+/* SDMMC1/3 settings from section 27.5 of T114 TRM */
+#define SDIOCFG_DRVUP_SLWF     0
+#define SDIOCFG_DRVDN_SLWR     0
+#define SDIOCFG_DRVUP          0x24
+#define SDIOCFG_DRVDN          0x14
+
 #endif /* _TEGRA114_GP_PADCTRL_H_ */
diff --git a/arch/arm/include/asm/arch-tegra114/tegra114_spi.h b/arch/arm/include/asm/arch-tegra114/tegra114_spi.h
new file mode 100644 (file)
index 0000000..48197bc
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * NVIDIA Tegra SPI controller
+ *
+ * Copyright 2010-2013 NVIDIA Corporation
+ *
+ * This software may be used and distributed according to the
+ * terms of the GNU Public License, Version 2, incorporated
+ * herein by reference.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _TEGRA114_SPI_H_
+#define _TEGRA114_SPI_H_
+
+#include <asm/types.h>
+
+int tegra114_spi_init(int *node_list, int count);
+int tegra114_spi_cs_is_valid(unsigned int bus, unsigned int cs);
+struct spi_slave *tegra114_spi_setup_slave(unsigned int bus, unsigned int cs,
+                                 unsigned int max_hz, unsigned int mode);
+void tegra114_spi_free_slave(struct spi_slave *slave);
+int tegra114_spi_claim_bus(struct spi_slave *slave);
+void tegra114_spi_cs_activate(struct spi_slave *slave);
+void tegra114_spi_cs_deactivate(struct spi_slave *slave);
+int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+                    const void *data_out, void *data_in, unsigned long flags);
+
+#endif /* _TEGRA114_SPI_H_ */
diff --git a/arch/arm/include/asm/arch-tegra20/tegra20_sflash.h b/arch/arm/include/asm/arch-tegra20/tegra20_sflash.h
new file mode 100644 (file)
index 0000000..e8cc68c
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * NVIDIA Tegra20 SPI-FLASH controller
+ *
+ * Copyright 2010-2012 NVIDIA Corporation
+ *
+ * This software may be used and distributed according to the
+ * terms of the GNU Public License, Version 2, incorporated
+ * herein by reference.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _TEGRA20_SPI_H_
+#define _TEGRA20_SPI_H_
+
+#include <asm/types.h>
+
+int tegra20_spi_cs_is_valid(unsigned int bus, unsigned int cs);
+struct spi_slave *tegra20_spi_setup_slave(unsigned int bus, unsigned int cs,
+                                 unsigned int max_hz, unsigned int mode);
+void tegra20_spi_free_slave(struct spi_slave *slave);
+int tegra20_spi_init(int *node_list, int count);
+int tegra20_spi_claim_bus(struct spi_slave *slave);
+void tegra20_spi_cs_activate(struct spi_slave *slave);
+void tegra20_spi_cs_deactivate(struct spi_slave *slave);
+int tegra20_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+            const void *data_out, void *data_in, unsigned long flags);
+
+#endif /* _TEGRA20_SPI_H_ */
diff --git a/arch/arm/include/asm/arch-tegra20/tegra20_slink.h b/arch/arm/include/asm/arch-tegra20/tegra20_slink.h
new file mode 100644 (file)
index 0000000..5aa74dd
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * NVIDIA Tegra SPI-SLINK controller
+ *
+ * Copyright 2010-2013 NVIDIA Corporation
+ *
+ * This software may be used and distributed according to the
+ * terms of the GNU Public License, Version 2, incorporated
+ * herein by reference.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _TEGRA30_SPI_H_
+#define _TEGRA30_SPI_H_
+
+#include <asm/types.h>
+
+int tegra30_spi_init(int *node_list, int count);
+int tegra30_spi_cs_is_valid(unsigned int bus, unsigned int cs);
+struct spi_slave *tegra30_spi_setup_slave(unsigned int bus, unsigned int cs,
+                                 unsigned int max_hz, unsigned int mode);
+void tegra30_spi_free_slave(struct spi_slave *slave);
+int tegra30_spi_claim_bus(struct spi_slave *slave);
+void tegra30_spi_cs_activate(struct spi_slave *slave);
+void tegra30_spi_cs_deactivate(struct spi_slave *slave);
+int tegra30_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+                    const void *data_out, void *data_in, unsigned long flags);
+
+#endif /* _TEGRA30_SPI_H_ */
index eef6a5a..8153484 100644 (file)
@@ -41,7 +41,9 @@ static inline void invalidate_l2_cache(void)
 
 void l2_cache_enable(void);
 void l2_cache_disable(void);
+void set_section_dcache(int section, enum dcache_option option);
 
+void dram_bank_mmu_setup(int bank);
 /*
  * The current upper bound for ARM L1 data cache line sizes is 64 bytes.  We
  * use that value for aligning DMA buffers unless the board config has specified
index 1918492..760345f 100644 (file)
@@ -81,6 +81,20 @@ static inline void set_cr(unsigned int val)
        isb();
 }
 
+static inline unsigned int get_dacr(void)
+{
+       unsigned int val;
+       asm("mrc p15, 0, %0, c3, c0, 0  @ get DACR" : "=r" (val) : : "cc");
+       return val;
+}
+
+static inline void set_dacr(unsigned int val)
+{
+       asm volatile("mcr p15, 0, %0, c3, c0, 0 @ set DACR"
+         : : "r" (val) : "cc");
+       isb();
+}
+
 /* options available for data cache on each page */
 enum dcache_option {
        DCACHE_OFF = 0x12,
index b6e5e95..4abe1cf 100644 (file)
@@ -23,6 +23,8 @@
 
 #include <common.h>
 #include <asm/system.h>
+#include <asm/cache.h>
+#include <linux/compiler.h>
 
 #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
 
@@ -34,6 +36,10 @@ void __arm_init_before_mmu(void)
 void arm_init_before_mmu(void)
        __attribute__((weak, alias("__arm_init_before_mmu")));
 
+__weak void arm_init_domains(void)
+{
+}
+
 static void cp_delay (void)
 {
        volatile int i;
@@ -77,7 +83,7 @@ void mmu_set_region_dcache_behaviour(u32 start, int size,
        mmu_page_table_flush((u32)&page_table[start], (u32)&page_table[end]);
 }
 
-static inline void dram_bank_mmu_setup(int bank)
+__weak void dram_bank_mmu_setup(int bank)
 {
        bd_t *bd = gd->bd;
        int     i;
@@ -115,6 +121,9 @@ static inline void mmu_setup(void)
        /* Set the access control to all-supervisor */
        asm volatile("mcr p15, 0, %0, c3, c0, 0"
                     : : "r" (~0));
+
+       arm_init_domains();
+
        /* and enable the mmu */
        reg = get_cr(); /* get control reg. */
        cp_delay();
index e0e8235..629ce4a 100644 (file)
@@ -34,7 +34,9 @@
 #include <i2c.h>
 #include <usb.h>
 #include <mmc.h>
+#include <nand.h>
 #include <twl4030.h>
+#include <bmp_layout.h>
 #include <linux/compiler.h>
 
 #include <asm/io.h>
@@ -76,6 +78,65 @@ static u32 gpmc_nand_config[GPMC_MAX_REG] = {
        0,
 };
 
+#ifdef CONFIG_LCD
+#ifdef CONFIG_CMD_NAND
+static int splash_load_from_nand(u32 bmp_load_addr)
+{
+       struct bmp_header *bmp_hdr;
+       int res, splash_screen_nand_offset = 0x100000;
+       size_t bmp_size, bmp_header_size = sizeof(struct bmp_header);
+
+       if (bmp_load_addr + bmp_header_size >= gd->start_addr_sp)
+               goto splash_address_too_high;
+
+       res = nand_read_skip_bad(&nand_info[nand_curr_device],
+                       splash_screen_nand_offset, &bmp_header_size,
+                       (u_char *)bmp_load_addr);
+       if (res < 0)
+               return res;
+
+       bmp_hdr = (struct bmp_header *)bmp_load_addr;
+       bmp_size = le32_to_cpu(bmp_hdr->file_size);
+
+       if (bmp_load_addr + bmp_size >= gd->start_addr_sp)
+               goto splash_address_too_high;
+
+       return nand_read_skip_bad(&nand_info[nand_curr_device],
+                       splash_screen_nand_offset, &bmp_size,
+                       (u_char *)bmp_load_addr);
+
+splash_address_too_high:
+       printf("Error: splashimage address too high. Data overwrites U-Boot "
+               "and/or placed beyond DRAM boundaries.\n");
+
+       return -1;
+}
+#else
+static inline int splash_load_from_nand(void)
+{
+       return -1;
+}
+#endif /* CONFIG_CMD_NAND */
+
+int board_splash_screen_prepare(void)
+{
+       char *env_splashimage_value;
+       u32 bmp_load_addr;
+
+       env_splashimage_value = getenv("splashimage");
+       if (env_splashimage_value == NULL)
+               return -1;
+
+       bmp_load_addr = simple_strtoul(env_splashimage_value, 0, 16);
+       if (bmp_load_addr == 0) {
+               printf("Error: bad splashimage address specified\n");
+               return -1;
+       }
+
+       return splash_load_from_nand(bmp_load_addr);
+}
+#endif /* CONFIG_LCD */
+
 /*
  * Routine: board_init
  * Description: hardware init.
index 7d9f361..8d7a227 100644 (file)
@@ -132,10 +132,7 @@ int board_init(void)
        clock_init();
        clock_verify();
 
-#ifdef CONFIG_SPI_UART_SWITCH
-       gpio_config_uart();
-#endif
-#if defined(CONFIG_TEGRA_SPI) || defined(CONFIG_TEGRA_SLINK)
+#ifdef CONFIG_FDT_SPI
        pin_mux_spi();
        spi_init();
 #endif
index bd6202c..d9bcb85 100644 (file)
@@ -1,4 +1,3 @@
 # common options for all tegra boards
 COBJS-y        += ../../nvidia/common/board.o
-COBJS-$(CONFIG_SPI_UART_SWITCH) += ../../nvidia/common/uart-spi-switch.o
 COBJS-$(CONFIG_TEGRA_CLOCK_SCALING) += ../../nvidia/common/emc.o
diff --git a/board/nvidia/common/uart-spi-switch.c b/board/nvidia/common/uart-spi-switch.c
deleted file mode 100644 (file)
index e9d445d..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2011 The Chromium OS Authors.
- *
- * 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/gpio.h>
-#include <asm/arch/pinmux.h>
-#include <asm/arch/uart-spi-switch.h>
-#include <asm/arch/tegra.h>
-#include <asm/arch-tegra/tegra_spi.h>
-#include <asm/arch-tegra/board.h>
-
-/* position of the UART/SPI select switch */
-enum spi_uart_switch {
-       SWITCH_UNKNOWN,
-       SWITCH_SPI,
-       SWITCH_UART,
-       SWITCH_BOTH
-};
-
-/* Information about the spi/uart switch */
-struct spi_uart {
-       int gpio;                       /* GPIO to control switch */
-       u32 port;                       /* Port number of UART affected */
-};
-
-static struct spi_uart local;
-static enum spi_uart_switch switch_pos; /* Current switch position */
-
-
-static void get_config(struct spi_uart *config)
-{
-#if defined CONFIG_SPI_CORRUPTS_UART
-       config->gpio = CONFIG_UART_DISABLE_GPIO;
-       config->port = CONFIG_SPI_CORRUPTS_UART_NR;
-#else
-       config->gpio = -1;
-#endif
-}
-
-/*
- * Init the UART / SPI switch. This can be called before relocation so we must
- * not access BSS.
- */
-void gpio_early_init_uart(void)
-{
-       struct spi_uart config;
-
-       get_config(&config);
-       if (config.gpio != -1) {
-               /* Cannot provide a label prior to relocation */
-               gpio_request(config.gpio, NULL);
-               gpio_direction_output(config.gpio, 0);
-       }
-}
-
-/*
- * Configure the UART / SPI switch.
- */
-void gpio_config_uart(void)
-{
-       get_config(&local);
-       if (local.gpio != -1) {
-               gpio_direction_output(local.gpio, 0);
-               switch_pos = SWITCH_UART;
-       } else {
-               /*
-                * If we're here we don't have a SPI switch; go ahead and
-                * enable the SPI now.  We didn't in spi_init() so we wouldn't
-                * kill the UART.
-                */
-               pinmux_set_func(PINGRP_GMC, PMUX_FUNC_SFLASH);
-               switch_pos = SWITCH_BOTH;
-       }
-}
-
-static void spi_uart_switch(struct spi_uart *config,
-                             enum spi_uart_switch new_pos)
-{
-       if (switch_pos == SWITCH_BOTH || new_pos == switch_pos)
-               return;
-
-       /* pre-delay, allow SPI/UART to settle, FIFO to empty, etc. */
-       udelay(CONFIG_SPI_CORRUPTS_UART_DLY);
-
-       /* We need to dynamically change the pinmux, shared w/UART RXD/CTS */
-       pinmux_set_func(PINGRP_GMC, new_pos == SWITCH_SPI ?
-                               PMUX_FUNC_SFLASH : PMUX_FUNC_UARTD);
-
-       /*
-        * On Seaboard, MOSI/MISO are shared w/UART.
-        * Use GPIO I3 (UART_DISABLE) to tristate UART during SPI activity.
-        * Enable UART later (cs_deactivate) so we can use it for U-Boot comms.
-        */
-       gpio_direction_output(config->gpio, new_pos == SWITCH_SPI);
-       switch_pos = new_pos;
-}
-
-void pinmux_select_uart(void)
-{
-               spi_uart_switch(&local, SWITCH_UART);
-}
-
-void pinmux_select_spi(void)
-{
-       spi_uart_switch(&local, SWITCH_SPI);
-}
index 2020a5f..2c23a29 100644 (file)
 
 #include <common.h>
 #include <asm/arch/pinmux.h>
+#include <asm/arch/gp_padctrl.h>
 #include "pinmux-config-dalmore.h"
+#include <i2c.h>
+
+#define BAT_I2C_ADDRESS                0x48    /* TPS65090 charger */
+#define PMU_I2C_ADDRESS                0x58    /* TPS65913 PMU */
 
 /*
  * Routine: pinmux_init
@@ -32,4 +37,65 @@ void pinmux_init(void)
 
        pinmux_config_table(unused_pins_lowpower,
                ARRAY_SIZE(unused_pins_lowpower));
+
+       /* Initialize any non-default pad configs (APB_MISC_GP regs) */
+       padgrp_config_table(dalmore_padctrl, ARRAY_SIZE(dalmore_padctrl));
+}
+
+#if defined(CONFIG_TEGRA_MMC)
+/*
+ * Do I2C/PMU writes to bring up SD card bus power
+ *
+ */
+void board_sdmmc_voltage_init(void)
+{
+       uchar reg, data_buffer[1];
+       int ret;
+
+       ret = i2c_set_bus_num(0);/* PMU is on bus 0 */
+       if (ret)
+               printf("%s: i2c_set_bus_num returned %d\n", __func__, ret);
+
+       /* TPS65913: LDO9_VOLTAGE = 3.3V */
+       data_buffer[0] = 0x31;
+       reg = 0x61;
+
+       ret = i2c_write(PMU_I2C_ADDRESS, reg, 1, data_buffer, 1);
+       if (ret)
+               printf("%s: PMU i2c_write %02X<-%02X returned %d\n",
+                       __func__, reg, data_buffer[0], ret);
+
+       /* TPS65913: LDO9_CTRL = Active */
+       data_buffer[0] = 0x01;
+       reg = 0x60;
+
+       ret = i2c_write(PMU_I2C_ADDRESS, reg, 1, data_buffer, 1);
+       if (ret)
+               printf("%s: PMU i2c_write %02X<-%02X returned %d\n",
+                       __func__, reg, data_buffer[0], ret);
+
+       /* TPS65090: FET6_CTRL = enable output auto discharge, enable FET6 */
+       data_buffer[0] = 0x03;
+       reg = 0x14;
+
+       ret = i2c_write(BAT_I2C_ADDRESS, reg, 1, data_buffer, 1);
+       if (ret)
+               printf("%s: BAT i2c_write %02X<-%02X returned %d\n",
+                       __func__, reg, data_buffer[0], ret);
+}
+
+/*
+ * Routine: pin_mux_mmc
+ * Description: setup the MMC muxes, power rails, etc.
+ */
+void pin_mux_mmc(void)
+{
+       /*
+        * NOTE: We don't do mmc-specific pin muxes here.
+        * They were done globally in pinmux_init().
+        */
+
+       /* Bring up the SDIO3 power rail */
+       board_sdmmc_voltage_init();
 }
+#endif /* MMC */
index 3ef6f4e..8c05a15 100644 (file)
@@ -361,4 +361,10 @@ static struct pingroup_config tegra114_pinmux_set_nontristate[] = {
 
        DEFAULT_PINMUX(SDMMC3_CD_N,     SDMMC3, UP,       NORMAL,   INPUT),
 };
+
+static struct padctrl_config dalmore_padctrl[] = {
+       /* (_padgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) */
+       DEFAULT_PADCFG(SDIO3, SDIOCFG_DRVUP_SLWF, SDIOCFG_DRVDN_SLWR, \
+               SDIOCFG_DRVUP, SDIOCFG_DRVDN, NONE, NONE, NONE),
+};
 #endif /* PINMUX_CONFIG_COMMON_H */
index 30cf1fb..86e9459 100644 (file)
@@ -12,6 +12,8 @@
                i2c2 = "/i2c@7000c400";
                i2c3 = "/i2c@7000c500";
                i2c4 = "/i2c@7000c700";
+               sdhci0 = "/sdhci@78000600";
+               sdhci1 = "/sdhci@78000400";
        };
 
        memory {
                status = "okay";
                clock-frequency = <400000>;
        };
+
+       spi@7000da00 {
+               status = "okay";
+               spi-max-frequency = <25000000>;
+       };
+
+       sdhci@78000400 {
+               cd-gpios = <&gpio 170 1>; /* gpio PV2 */
+               bus-width = <4>;
+               status = "okay";
+       };
+
+       sdhci@78000600 {
+               bus-width = <8>;
+               status = "okay";
+       };
 };
index e581fdd..498e513 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/gpio.h>
 
 /* TODO: Remove this code when the SPI switch is working */
-#if !defined(CONFIG_SPI_UART_SWITCH) && (CONFIG_MACH_TYPE != MACH_TYPE_VENTANA)
+#if (CONFIG_MACH_TYPE != MACH_TYPE_VENTANA)
 void gpio_early_init_uart(void)
 {
        /* Enable UART via GPIO_PI3 (port 8, bit 3) so serial console works */
index 55bc018..1708ac2 100644 (file)
@@ -61,7 +61,7 @@ static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
 
 static void rtc32k_enable(void)
 {
-       struct rtc_regs *rtc = (struct rtc_regs *)AM335X_RTC_BASE;
+       struct rtc_regs *rtc = (struct rtc_regs *)RTC_BASE;
 
        /*
         * Unlock the RTC's registers.  For more details please see the
@@ -159,7 +159,7 @@ void s_init(void)
        enable_board_pin_mux();
 
        config_ddr(DDR_CLK_MHZ, MT41J256M8HX15E_IOCTRL_VALUE, &ddr3_data,
-                       &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data);
+                       &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);
 #endif
 }
 
@@ -199,8 +199,8 @@ static struct cpsw_slave_data cpsw_slaves[] = {
 };
 
 static struct cpsw_platform_data cpsw_data = {
-       .mdio_base              = AM335X_CPSW_MDIO_BASE,
-       .cpsw_base              = AM335X_CPSW_BASE,
+       .mdio_base              = CPSW_MDIO_BASE,
+       .cpsw_base              = CPSW_BASE,
        .mdio_div               = 0xff,
        .channels               = 8,
        .cpdma_reg_ofs          = 0x800,
index 688b0aa..6b3e095 100644 (file)
  */
 
 #include <common.h>
+#include <asm/arch/mbox.h>
+#include <asm/arch/sdhci.h>
 #include <asm/global_data.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+struct msg_get_arm_mem {
+       struct bcm2835_mbox_hdr hdr;
+       struct bcm2835_mbox_tag_get_arm_mem get_arm_mem;
+       u32 end_tag;
+};
+
+struct msg_get_clock_rate {
+       struct bcm2835_mbox_hdr hdr;
+       struct bcm2835_mbox_tag_get_clock_rate get_clock_rate;
+       u32 end_tag;
+};
+
 int dram_init(void)
 {
-       gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+       ALLOC_ALIGN_BUFFER(struct msg_get_arm_mem, msg, 1, 16);
+       int ret;
+
+       BCM2835_MBOX_INIT_HDR(msg);
+       BCM2835_MBOX_INIT_TAG(&msg->get_arm_mem, GET_ARM_MEMORY);
+
+       ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr);
+       if (ret) {
+               printf("bcm2835: Could not query ARM memory size\n");
+               return -1;
+       }
+
+       gd->ram_size = msg->get_arm_mem.body.resp.mem_size;
 
        return 0;
 }
@@ -32,3 +58,22 @@ int board_init(void)
 
        return 0;
 }
+
+int board_mmc_init(void)
+{
+       ALLOC_ALIGN_BUFFER(struct msg_get_clock_rate, msg_clk, 1, 16);
+       int ret;
+
+       BCM2835_MBOX_INIT_HDR(msg_clk);
+       BCM2835_MBOX_INIT_TAG(&msg_clk->get_clock_rate, GET_CLOCK_RATE);
+       msg_clk->get_clock_rate.body.req.clock_id = BCM2835_MBOX_CLOCK_ID_EMMC;
+
+       ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_clk->hdr);
+       if (ret) {
+               printf("bcm2835: Could not query eMMC clock rate\n");
+               return -1;
+       }
+
+       return bcm2835_sdhci_init(BCM2835_SDHCI_BASE,
+                                 msg_clk->get_clock_rate.body.resp.rate_hz);
+}
index cbfab6f..1c2d52d 100644 (file)
                        compatible = "maxim,max77686_pmic";
                };
        };
+
+       tmu@10060000 {
+               samsung,min-temp        = <25>;
+               samsung,max-temp        = <125>;
+               samsung,start-warning   = <95>;
+               samsung,start-tripping  = <105>;
+               samsung,hw-tripping     = <110>;
+               samsung,efuse-min-value = <40>;
+               samsung,efuse-value     = <55>;
+               samsung,efuse-max-value = <100>;
+               samsung,slope           = <274761730>;
+               samsung,dc-value        = <25>;
+       };
 };
diff --git a/board/samsung/dts/exynos5250-snow.dts b/board/samsung/dts/exynos5250-snow.dts
new file mode 100644 (file)
index 0000000..8b303bf
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * SAMSUNG Snow board device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * 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.
+*/
+
+/dts-v1/;
+/include/ ARCH_CPU_DTS
+
+/ {
+       model = "Google Snow";
+       compatible = "google,snow", "samsung,exynos5250";
+
+       aliases {
+               i2c0 = "/i2c@12c60000";
+               i2c1 = "/i2c@12c70000";
+               i2c2 = "/i2c@12c80000";
+               i2c3 = "/i2c@12c90000";
+               i2c4 = "/i2c@12ca0000";
+               i2c5 = "/i2c@12cb0000";
+               i2c6 = "/i2c@12cc0000";
+               i2c7 = "/i2c@12cd0000";
+               spi0 = "/spi@12d20000";
+               spi1 = "/spi@12d30000";
+               spi2 = "/spi@12d40000";
+               spi3 = "/spi@131a0000";
+               spi4 = "/spi@131b0000";
+       };
+
+       sound@12d60000 {
+               samsung,i2s-epll-clock-frequency = <192000000>;
+               samsung,i2s-sampling-rate = <48000>;
+               samsung,i2s-bits-per-sample = <16>;
+               samsung,i2s-channels = <2>;
+               samsung,i2s-lr-clk-framesize = <256>;
+               samsung,i2s-bit-clk-framesize = <32>;
+               samsung,codec-type = "max98095";
+       };
+
+       i2c@12cd0000 {
+               soundcodec@22 {
+                       reg = <0x22>;
+                       compatible = "maxim,max98095-codec";
+               };
+       };
+
+       i2c@12c60000 {
+               pmic@9 {
+                       reg = <0x9>;
+                       compatible = "maxim,max77686_pmic";
+               };
+       };
+};
index 7a5f132..217c6df 100644 (file)
@@ -23,6 +23,7 @@
 #include <common.h>
 #include <fdtdec.h>
 #include <asm/io.h>
+#include <errno.h>
 #include <i2c.h>
 #include <lcd.h>
 #include <netdev.h>
 #include <asm/arch/sromc.h>
 #include <asm/arch/dp_info.h>
 #include <power/pmic.h>
+#include <power/max77686_pmic.h>
+#include <tmu.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#if defined CONFIG_EXYNOS_TMU
+/*
+ * Boot Time Thermal Analysis for SoC temperature threshold breach
+ */
+static void boot_temp_check(void)
+{
+       int temp;
+
+       switch (tmu_monitor(&temp)) {
+       /* Status TRIPPED ans WARNING means corresponding threshold breach */
+       case TMU_STATUS_TRIPPED:
+               puts("EXYNOS_TMU: TRIPPING! Device power going down ...\n");
+               set_ps_hold_ctrl();
+               hang();
+               break;
+       case TMU_STATUS_WARNING:
+               puts("EXYNOS_TMU: WARNING! Temperature very high\n");
+               break;
+       /*
+        * TMU_STATUS_INIT means something is wrong with temperature sensing
+        * and TMU status was changed back from NORMAL to INIT.
+        */
+       case TMU_STATUS_INIT:
+       default:
+               debug("EXYNOS_TMU: Unknown TMU state\n");
+       }
+}
+#endif
+
 #ifdef CONFIG_USB_EHCI_EXYNOS
 int board_usb_vbus_init(void)
 {
@@ -54,14 +86,38 @@ int board_usb_vbus_init(void)
 }
 #endif
 
+#ifdef CONFIG_SOUND_MAX98095
+static void  board_enable_audio_codec(void)
+{
+       struct exynos5_gpio_part1 *gpio1 = (struct exynos5_gpio_part1 *)
+                                               samsung_get_base_gpio_part1();
+
+       /* Enable MAX98095 Codec */
+       s5p_gpio_direction_output(&gpio1->x1, 7, 1);
+       s5p_gpio_set_pull(&gpio1->x1, 7, GPIO_PULL_NONE);
+}
+#endif
+
 int board_init(void)
 {
        gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
+
+#if defined CONFIG_EXYNOS_TMU
+       if (tmu_init(gd->fdt_blob) != TMU_STATUS_NORMAL) {
+               debug("%s: Failed to init TMU\n", __func__);
+               return -1;
+       }
+       boot_temp_check();
+#endif
+
 #ifdef CONFIG_EXYNOS_SPI
        spi_init();
 #endif
 #ifdef CONFIG_USB_EHCI_EXYNOS
        board_usb_vbus_init();
+#endif
+#ifdef CONFIG_SOUND_MAX98095
+       board_enable_audio_codec();
 #endif
        return 0;
 }
@@ -80,12 +136,119 @@ int dram_init(void)
 }
 
 #if defined(CONFIG_POWER)
+static int pmic_reg_update(struct pmic *p, int reg, uint regval)
+{
+       u32 val;
+       int ret = 0;
+
+       ret = pmic_reg_read(p, reg, &val);
+       if (ret) {
+               debug("%s: PMIC %d register read failed\n", __func__, reg);
+               return -1;
+       }
+       val |= regval;
+       ret = pmic_reg_write(p, reg, val);
+       if (ret) {
+               debug("%s: PMIC %d register write failed\n", __func__, reg);
+               return -1;
+       }
+       return 0;
+}
+
 int power_init_board(void)
 {
+       struct pmic *p;
+
+       set_ps_hold_ctrl();
+
+       i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
        if (pmic_init(I2C_PMIC))
                return -1;
-       else
-               return 0;
+
+       p = pmic_get("MAX77686_PMIC");
+       if (!p)
+               return -ENODEV;
+
+       if (pmic_probe(p))
+               return -1;
+
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_32KHZ, MAX77686_32KHCP_EN))
+               return -1;
+
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_BBAT,
+                               MAX77686_BBCHOSTEN | MAX77686_BBCVS_3_5V))
+               return -1;
+
+       /* VDD_MIF */
+       if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK1OUT,
+                                               MAX77686_BUCK1OUT_1V)) {
+               debug("%s: PMIC %d register write failed\n", __func__,
+                                               MAX77686_REG_PMIC_BUCK1OUT);
+               return -1;
+       }
+
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK1CRTL,
+                                               MAX77686_BUCK1CTRL_EN))
+               return -1;
+
+       /* VDD_ARM */
+       if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK2DVS1,
+                                       MAX77686_BUCK2DVS1_1_3V)) {
+               debug("%s: PMIC %d register write failed\n", __func__,
+                                               MAX77686_REG_PMIC_BUCK2DVS1);
+               return -1;
+       }
+
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK2CTRL1,
+                                       MAX77686_BUCK2CTRL_ON))
+               return -1;
+
+       /* VDD_INT */
+       if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK3DVS1,
+                                       MAX77686_BUCK3DVS1_1_0125V)) {
+               debug("%s: PMIC %d register write failed\n", __func__,
+                                               MAX77686_REG_PMIC_BUCK3DVS1);
+               return -1;
+       }
+
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK3CTRL,
+                                       MAX77686_BUCK3CTRL_ON))
+               return -1;
+
+       /* VDD_G3D */
+       if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK4DVS1,
+                                       MAX77686_BUCK4DVS1_1_2V)) {
+               debug("%s: PMIC %d register write failed\n", __func__,
+                                               MAX77686_REG_PMIC_BUCK4DVS1);
+               return -1;
+       }
+
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK4CTRL1,
+                                       MAX77686_BUCK3CTRL_ON))
+               return -1;
+
+       /* VDD_LDO2 */
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO2CTRL1,
+                               MAX77686_LD02CTRL1_1_5V | EN_LDO))
+               return -1;
+
+       /* VDD_LDO3 */
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO3CTRL1,
+                               MAX77686_LD03CTRL1_1_8V | EN_LDO))
+               return -1;
+
+       /* VDD_LDO5 */
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO5CTRL1,
+                               MAX77686_LD05CTRL1_1_8V | EN_LDO))
+               return -1;
+
+       /* VDD_LDO10 */
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO10CTRL1,
+                               MAX77686_LD10CTRL1_1_8V | EN_LDO))
+               return -1;
+
+       return 0;
 }
 #endif
 
@@ -212,8 +375,17 @@ int board_eth_init(bd_t *bis)
 #ifdef CONFIG_DISPLAY_BOARDINFO
 int checkboard(void)
 {
-       printf("\nBoard: SMDK5250\n");
+#ifdef CONFIG_OF_CONTROL
+       const char *board_name;
 
+       board_name = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
+       if (board_name == NULL)
+               printf("\nUnknown Board\n");
+       else
+               printf("\nBoard: %s\n", board_name);
+#else
+       printf("\nBoard: SMDK5250\n");
+#endif
        return 0;
 }
 #endif
index f4b972b..12620bb 100644 (file)
@@ -134,7 +134,7 @@ static int read_eeprom(void)
 
 static void rtc32k_enable(void)
 {
-       struct rtc_regs *rtc = (struct rtc_regs *)AM335X_RTC_BASE;
+       struct rtc_regs *rtc = (struct rtc_regs *)RTC_BASE;
 
        /*
         * Unlock the RTC's registers.  For more details please see the
@@ -208,6 +208,14 @@ static const struct ddr_data ddr3_data = {
        .datadldiff0 = PHY_DLL_LOCK_DIFF,
 };
 
+static const struct ddr_data ddr3_beagleblack_data = {
+       .datardsratio0 = MT41K256M16HA125E_RD_DQS,
+       .datawdsratio0 = MT41K256M16HA125E_WR_DQS,
+       .datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE,
+       .datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA,
+       .datadldiff0 = PHY_DLL_LOCK_DIFF,
+};
+
 static const struct ddr_data ddr3_evm_data = {
        .datardsratio0 = MT41J512M8RH125_RD_DQS,
        .datawdsratio0 = MT41J512M8RH125_WR_DQS,
@@ -230,6 +238,20 @@ static const struct cmd_control ddr3_cmd_ctrl_data = {
        .cmd2iclkout = MT41J128MJT125_INVERT_CLKOUT,
 };
 
+static const struct cmd_control ddr3_beagleblack_cmd_ctrl_data = {
+       .cmd0csratio = MT41K256M16HA125E_RATIO,
+       .cmd0dldiff = MT41K256M16HA125E_DLL_LOCK_DIFF,
+       .cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
+
+       .cmd1csratio = MT41K256M16HA125E_RATIO,
+       .cmd1dldiff = MT41K256M16HA125E_DLL_LOCK_DIFF,
+       .cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
+
+       .cmd2csratio = MT41K256M16HA125E_RATIO,
+       .cmd2dldiff = MT41K256M16HA125E_DLL_LOCK_DIFF,
+       .cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
+};
+
 static const struct cmd_control ddr3_evm_cmd_ctrl_data = {
        .cmd0csratio = MT41J512M8RH125_RATIO,
        .cmd0dldiff = MT41J512M8RH125_DLL_LOCK_DIFF,
@@ -251,7 +273,18 @@ static struct emif_regs ddr3_emif_reg_data = {
        .sdram_tim2 = MT41J128MJT125_EMIF_TIM2,
        .sdram_tim3 = MT41J128MJT125_EMIF_TIM3,
        .zq_config = MT41J128MJT125_ZQ_CFG,
-       .emif_ddr_phy_ctlr_1 = MT41J128MJT125_EMIF_READ_LATENCY,
+       .emif_ddr_phy_ctlr_1 = MT41J128MJT125_EMIF_READ_LATENCY |
+                               PHY_EN_DYN_PWRDN,
+};
+
+static struct emif_regs ddr3_beagleblack_emif_reg_data = {
+       .sdram_config = MT41K256M16HA125E_EMIF_SDCFG,
+       .ref_ctrl = MT41K256M16HA125E_EMIF_SDREF,
+       .sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1,
+       .sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2,
+       .sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3,
+       .zq_config = MT41K256M16HA125E_ZQ_CFG,
+       .emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY,
 };
 
 static struct emif_regs ddr3_evm_emif_reg_data = {
@@ -261,7 +294,8 @@ static struct emif_regs ddr3_evm_emif_reg_data = {
        .sdram_tim2 = MT41J512M8RH125_EMIF_TIM2,
        .sdram_tim3 = MT41J512M8RH125_EMIF_TIM3,
        .zq_config = MT41J512M8RH125_ZQ_CFG,
-       .emif_ddr_phy_ctlr_1 = MT41J512M8RH125_EMIF_READ_LATENCY,
+       .emif_ddr_phy_ctlr_1 = MT41J512M8RH125_EMIF_READ_LATENCY |
+                               PHY_EN_DYN_PWRDN,
 };
 #endif
 
@@ -341,15 +375,20 @@ void s_init(void)
                gpio_direction_output(GPIO_DDR_VTT_EN, 1);
        }
 
-       if (board_is_evm_sk() || board_is_bone_lt())
+       if (board_is_evm_sk())
                config_ddr(303, MT41J128MJT125_IOCTRL_VALUE, &ddr3_data,
-                          &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data);
+                          &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);
+       else if (board_is_bone_lt())
+               config_ddr(303, MT41K256M16HA125E_IOCTRL_VALUE,
+                          &ddr3_beagleblack_data,
+                          &ddr3_beagleblack_cmd_ctrl_data,
+                          &ddr3_beagleblack_emif_reg_data, 0);
        else if (board_is_evm_15_or_later())
                config_ddr(303, MT41J512M8RH125_IOCTRL_VALUE, &ddr3_evm_data,
-                          &ddr3_evm_cmd_ctrl_data, &ddr3_evm_emif_reg_data);
+                          &ddr3_evm_cmd_ctrl_data, &ddr3_evm_emif_reg_data, 0);
        else
                config_ddr(266, MT47H128M16RT25E_IOCTRL_VALUE, &ddr2_data,
-                          &ddr2_cmd_ctrl_data, &ddr2_emif_reg_data);
+                          &ddr2_cmd_ctrl_data, &ddr2_emif_reg_data, 0);
 #endif
 }
 
@@ -412,8 +451,8 @@ static struct cpsw_slave_data cpsw_slaves[] = {
 };
 
 static struct cpsw_platform_data cpsw_data = {
-       .mdio_base              = AM335X_CPSW_MDIO_BASE,
-       .cpsw_base              = AM335X_CPSW_BASE,
+       .mdio_base              = CPSW_MDIO_BASE,
+       .cpsw_base              = CPSW_BASE,
        .mdio_div               = 0xff,
        .channels               = 8,
        .cpdma_reg_ofs          = 0x800,
diff --git a/board/ti/ti814x/Makefile b/board/ti/ti814x/Makefile
new file mode 100644 (file)
index 0000000..09d2422
--- /dev/null
@@ -0,0 +1,46 @@
+#
+# Makefile
+#
+# Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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 "as is" WITHOUT ANY WARRANTY of any
+# kind, whether express or implied; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    = $(obj)lib$(BOARD).o
+
+ifdef CONFIG_SPL_BUILD
+COBJS  := mux.o
+endif
+
+COBJS  += evm.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
+
+#########################################################################
diff --git a/board/ti/ti814x/evm.c b/board/ti/ti814x/evm.c
new file mode 100644 (file)
index 0000000..446e36b
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * evm.c
+ *
+ * Board functions for TI814x EVM
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.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.
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <spl.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/omap.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mmc_host_def.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+#include <asm/emif.h>
+#include <asm/gpio.h>
+#include "evm.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_SPL_BUILD
+static struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
+static struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
+#endif
+
+/* UART Defines */
+#ifdef CONFIG_SPL_BUILD
+#define UART_RESET             (0x1 << 1)
+#define UART_CLK_RUNNING_MASK  0x1
+#define UART_SMART_IDLE_EN     (0x1 << 0x3)
+
+static void rtc32k_enable(void)
+{
+       struct rtc_regs *rtc = (struct rtc_regs *)RTC_BASE;
+
+       /*
+        * Unlock the RTC's registers.  For more details please see the
+        * RTC_SS section of the TRM.  In order to unlock we need to
+        * write these specific values (keys) in this order.
+        */
+       writel(0x83e70b13, &rtc->kick0r);
+       writel(0x95a4f1e0, &rtc->kick1r);
+
+       /* Enable the RTC 32K OSC by setting bits 3 and 6. */
+       writel((1 << 3) | (1 << 6), &rtc->osc);
+}
+
+static void uart_enable(void)
+{
+       u32 regVal;
+
+       /* UART softreset */
+       regVal = readl(&uart_base->uartsyscfg);
+       regVal |= UART_RESET;
+       writel(regVal, &uart_base->uartsyscfg);
+       while ((readl(&uart_base->uartsyssts) &
+               UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK)
+               ;
+
+       /* Disable smart idle */
+       regVal = readl(&uart_base->uartsyscfg);
+       regVal |= UART_SMART_IDLE_EN;
+       writel(regVal, &uart_base->uartsyscfg);
+}
+
+static void wdt_disable(void)
+{
+       writel(0xAAAA, &wdtimer->wdtwspr);
+       while (readl(&wdtimer->wdtwwps) != 0x0)
+               ;
+       writel(0x5555, &wdtimer->wdtwspr);
+       while (readl(&wdtimer->wdtwwps) != 0x0)
+               ;
+}
+
+static const struct cmd_control evm_ddr2_cctrl_data = {
+       .cmd0csratio    = 0x80,
+       .cmd0dldiff     = 0x04,
+       .cmd0iclkout    = 0x00,
+
+       .cmd1csratio    = 0x80,
+       .cmd1dldiff     = 0x04,
+       .cmd1iclkout    = 0x00,
+
+       .cmd2csratio    = 0x80,
+       .cmd2dldiff     = 0x04,
+       .cmd2iclkout    = 0x00,
+};
+
+static const struct emif_regs evm_ddr2_emif0_regs = {
+       .sdram_config                   = 0x40801ab2,
+       .ref_ctrl                       = 0x10000c30,
+       .sdram_tim1                     = 0x0aaaf552,
+       .sdram_tim2                     = 0x043631d2,
+       .sdram_tim3                     = 0x00000327,
+       .emif_ddr_phy_ctlr_1            = 0x00000007
+};
+
+static const struct emif_regs evm_ddr2_emif1_regs = {
+       .sdram_config                   = 0x40801ab2,
+       .ref_ctrl                       = 0x10000c30,
+       .sdram_tim1                     = 0x0aaaf552,
+       .sdram_tim2                     = 0x043631d2,
+       .sdram_tim3                     = 0x00000327,
+       .emif_ddr_phy_ctlr_1            = 0x00000007
+};
+
+const struct dmm_lisa_map_regs evm_lisa_map_regs = {
+       .dmm_lisa_map_0                 = 0x00000000,
+       .dmm_lisa_map_1                 = 0x00000000,
+       .dmm_lisa_map_2                 = 0x806c0300,
+       .dmm_lisa_map_3                 = 0x806c0300,
+};
+
+static const struct ddr_data evm_ddr2_data = {
+       .datardsratio0          = ((0x35<<10) | (0x35<<0)),
+       .datawdsratio0          = ((0x20<<10) | (0x20<<0)),
+       .datawiratio0           = ((0<<10) | (0<<0)),
+       .datagiratio0           = ((0<<10) | (0<<0)),
+       .datafwsratio0          = ((0x90<<10) | (0x90<<0)),
+       .datawrsratio0          = ((0x50<<10) | (0x50<<0)),
+       .datauserank0delay      = 1,
+       .datadldiff0            = 0x4,
+};
+#endif
+
+/*
+ * early system init of muxing and clocks.
+ */
+void s_init(void)
+{
+#ifdef CONFIG_SPL_BUILD
+       /* WDT1 is already running when the bootloader gets control
+        * Disable it to avoid "random" resets
+        */
+       wdt_disable();
+
+       /* Setup the PLLs and the clocks for the peripherals */
+       pll_init();
+
+       /* Enable RTC32K clock */
+       rtc32k_enable();
+
+       /* Set UART pins */
+       enable_uart0_pin_mux();
+
+       /* Set MMC pins */
+       enable_mmc1_pin_mux();
+
+       /* Enable UART */
+       uart_enable();
+
+       gd = &gdata;
+
+       preloader_console_init();
+
+       config_dmm(&evm_lisa_map_regs);
+
+       config_ddr(0, 0, &evm_ddr2_data, &evm_ddr2_cctrl_data,
+                  &evm_ddr2_emif0_regs, 0);
+       config_ddr(0, 0, &evm_ddr2_data, &evm_ddr2_cctrl_data,
+                  &evm_ddr2_emif1_regs, 1);
+#endif
+}
+
+/*
+ * Basic board specific setup.  Pinmux has been handled already.
+ */
+int board_init(void)
+{
+       gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
+       return 0;
+}
+
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_GENERIC_MMC)
+int board_mmc_init(bd_t *bis)
+{
+       omap_mmc_init(1, 0, 0, -1, -1);
+
+       return 0;
+}
+#endif
diff --git a/board/ti/ti814x/evm.h b/board/ti/ti814x/evm.h
new file mode 100644 (file)
index 0000000..40f8710
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _EVM_H
+#define _EVM_H
+
+void enable_uart0_pin_mux(void);
+void enable_mmc1_pin_mux(void);
+
+#endif /* _EVM_H */
diff --git a/board/ti/ti814x/mux.c b/board/ti/ti814x/mux.c
new file mode 100644 (file)
index 0000000..137acb4
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * mux.c
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/mux.h>
+#include <asm/io.h>
+#include <i2c.h>
+#include "evm.h"
+
+static struct module_pin_mux uart0_pin_mux[] = {
+       {OFFSET(pincntl70), PULLUP_EN | MODE(0x01)},    /* UART0_RXD */
+       {OFFSET(pincntl71), PULLUP_EN | MODE(0x01)},    /* UART0_TXD */
+       {-1},
+};
+
+static struct module_pin_mux mmc1_pin_mux[] = {
+       {OFFSET(pincntl1), PULLUP_EN | MODE(0x01)},     /* SD1_CLK */
+       {OFFSET(pincntl2), PULLUP_EN | MODE(0x01)},     /* SD1_CMD */
+       {OFFSET(pincntl3), PULLUP_EN | MODE(0x01)},     /* SD1_DAT[0] */
+       {OFFSET(pincntl4), PULLUP_EN | MODE(0x01)},     /* SD1_DAT[1] */
+       {OFFSET(pincntl5), PULLUP_EN | MODE(0x01)},     /* SD1_DAT[2] */
+       {OFFSET(pincntl6), PULLUP_EN | MODE(0x01)},     /* SD1_DAT[3] */
+       {OFFSET(pincntl74), PULLUP_EN | MODE(0x40)},    /* SD1_POW */
+       {OFFSET(pincntl75), MODE(0x40)},                /* SD1_SDWP */
+       {OFFSET(pincntl80), PULLUP_EN | MODE(0x02)},    /* SD1_SDCD */
+       {-1},
+};
+
+void enable_uart0_pin_mux(void)
+{
+       configure_module_pin_mux(uart0_pin_mux);
+}
+
+void enable_mmc1_pin_mux(void)
+{
+       configure_module_pin_mux(mmc1_pin_mux);
+}
index ee68fdd..5fc70be 100644 (file)
@@ -241,6 +241,7 @@ am335x_evm_uart3             arm         armv7       am335x              ti
 am335x_evm_uart4             arm         armv7       am335x              ti             am33xx      am335x_evm:SERIAL5,CONS_INDEX=5
 am335x_evm_uart5             arm         armv7       am335x              ti             am33xx      am335x_evm:SERIAL6,CONS_INDEX=6
 am335x_evm_usbspl            arm         armv7       am335x              ti             am33xx      am335x_evm:SERIAL1,CONS_INDEX=1,SPL_USBETH_SUPPORT
+ti814x_evm                   arm         armv7       ti814x              ti             am33xx
 pcm051                       arm         armv7       pcm051              phytec         am33xx      pcm051
 highbank                     arm         armv7       highbank            -              highbank
 mx51_efikamx                 arm         armv7       mx51_efikamx        genesi         mx5            mx51_efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKAMX,IMX_CONFIG=board/genesi/mx51_efikamx/imximage_mx.cfg
@@ -297,6 +298,7 @@ s5p_goni                     arm         armv7       goni                samsung
 smdkc100                     arm         armv7       smdkc100            samsung        s5pc1xx
 origen                      arm         armv7       origen              samsung        exynos
 s5pc210_universal            arm         armv7       universal_c210      samsung        exynos
+snow                        arm         armv7       smdk5250            samsung        exynos
 smdk5250                    arm         armv7       smdk5250            samsung        exynos
 smdkv310                    arm         armv7       smdkv310            samsung        exynos
 trats                        arm         armv7       trats               samsung        exynos
index 5d2ce00..7438469 100644 (file)
@@ -128,6 +128,9 @@ static boot_os_fn do_bootm_rtems;
 #if defined(CONFIG_BOOTM_OSE)
 static boot_os_fn do_bootm_ose;
 #endif
+#if defined(CONFIG_BOOTM_PLAN9)
+static boot_os_fn do_bootm_plan9;
+#endif
 #if defined(CONFIG_CMD_ELF)
 static boot_os_fn do_bootm_vxworks;
 static boot_os_fn do_bootm_qnxelf;
@@ -154,6 +157,9 @@ static boot_os_fn *boot_os[] = {
 #if defined(CONFIG_BOOTM_OSE)
        [IH_OS_OSE] = do_bootm_ose,
 #endif
+#if defined(CONFIG_BOOTM_PLAN9)
+       [IH_OS_PLAN9] = do_bootm_plan9,
+#endif
 #if defined(CONFIG_CMD_ELF)
        [IH_OS_VXWORKS] = do_bootm_vxworks,
        [IH_OS_QNX] = do_bootm_qnxelf,
@@ -1628,6 +1634,39 @@ static int do_bootm_ose(int flag, int argc, char * const argv[],
 }
 #endif /* CONFIG_BOOTM_OSE */
 
+#if defined(CONFIG_BOOTM_PLAN9)
+static int do_bootm_plan9(int flag, int argc, char * const argv[],
+                          bootm_headers_t *images)
+{
+       void (*entry_point)(void);
+
+       if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
+               return 1;
+
+#if defined(CONFIG_FIT)
+       if (!images->legacy_hdr_valid) {
+               fit_unsupported_reset("Plan 9");
+               return 1;
+       }
+#endif
+
+       entry_point = (void (*)(void))images->ep;
+
+       printf("## Transferring control to Plan 9 (at address %08lx) ...\n",
+               (ulong)entry_point);
+
+       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+       /*
+        * Plan 9 Parameters:
+        *   None
+        */
+       (*entry_point)();
+
+       return 1;
+}
+#endif /* CONFIG_BOOTM_PLAN9 */
+
 #if defined(CONFIG_CMD_ELF)
 static int do_bootm_vxworks(int flag, int argc, char * const argv[],
                             bootm_headers_t *images)
index cd94423..edbd4a8 100644 (file)
@@ -27,7 +27,9 @@
 
 #include <dtt.h>
 #include <i2c.h>
+#include <tmu.h>
 
+#if defined CONFIG_DTT_SENSORS
 static unsigned long sensor_initialized;
 
 static void _initialize_dtt(void)
@@ -59,9 +61,11 @@ void dtt_init(void)
        /* switch back to original I2C bus */
        I2C_SET_BUS(old_bus);
 }
+#endif
 
-int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+int dtt_i2c(void)
 {
+#if defined CONFIG_DTT_SENSORS
        int i;
        unsigned char sensors[] = CONFIG_DTT_SENSORS;
        int old_bus;
@@ -83,8 +87,34 @@ int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 
        /* switch back to original I2C bus */
        I2C_SET_BUS(old_bus);
+#endif
 
        return 0;
+}
+
+int dtt_tmu(void)
+{
+#if defined CONFIG_TMU_CMD_DTT
+       int cur_temp;
+
+       /* Sense and return latest thermal info */
+       if (tmu_monitor(&cur_temp) == TMU_STATUS_INIT) {
+               puts("TMU is in unknown state, temperature is invalid\n");
+               return -1;
+       }
+       printf("Current temperature: %u degrees Celsius\n", cur_temp);
+#endif
+       return 0;
+}
+
+int do_dtt(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       int err = 0;
+
+       err |= dtt_i2c();
+       err |= dtt_tmu();
+
+       return err;
 }      /* do_dtt() */
 
 /***************************************************/
index dcf76a5..706fd54 100644 (file)
@@ -88,10 +88,10 @@ int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc,
        dev = dev_desc->dev;
 
        /* get the filename */
-       filename = argv[3];
+       filename = argv[4];
 
        /* get the address in hexadecimal format (string to int) */
-       ram_address = simple_strtoul(argv[4], NULL, 16);
+       ram_address = simple_strtoul(argv[3], NULL, 16);
 
        /* get the filesize in base 10 format */
        file_size = simple_strtoul(argv[5], NULL, 10);
@@ -122,7 +122,7 @@ fail:
 
 U_BOOT_CMD(ext4write, 6, 1, do_ext4_write,
        "create a file in the root directory",
-       "<interface> <dev[:part]> [Absolute filename path] [Address] [sizebytes]\n"
+       "<interface> <dev[:part]> <addr> <absolute filename path> [sizebytes]\n"
        "    - create a file in / directory");
 
 #endif
index 78ca367..78aafb4 100644 (file)
@@ -31,7 +31,7 @@ DECLARE_GLOBAL_DATA_PTR;
 /*
  * Look up a callback function pointer by name
  */
-struct env_clbk_tbl *find_env_callback(const char *name)
+static struct env_clbk_tbl *find_env_callback(const char *name)
 {
        struct env_clbk_tbl *clbkp;
        int i;
index 6afbb40..60c2127 100644 (file)
@@ -108,6 +108,7 @@ static const table_entry_t uimage_os[] = {
 #endif
        {       IH_OS_NETBSD,   "netbsd",       "NetBSD",               },
        {       IH_OS_OSE,      "ose",          "Enea OSE",             },
+       {       IH_OS_PLAN9,    "plan9",        "Plan 9",               },
        {       IH_OS_RTEMS,    "rtems",        "RTEMS",                },
        {       IH_OS_U_BOOT,   "u-boot",       "U-Boot",               },
 #if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)
index 195f1de..b98eea6 100644 (file)
@@ -411,8 +411,6 @@ int drv_lcd_init(void)
 
        lcd_base = (void *) gd->fb_base;
 
-       lcd_get_size(&lcd_line_length);
-
        lcd_init(lcd_base);             /* LCD initialization */
 
        /* Device initialization */
@@ -495,6 +493,8 @@ static int lcd_init(void *lcdbase)
        debug("[LCD] Initializing LCD frambuffer at %p\n", lcdbase);
 
        lcd_ctrl_init(lcdbase);
+       lcd_get_size(&lcd_line_length);
+       lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
        lcd_is_enabled = 1;
        lcd_clear();
        lcd_enable();
diff --git a/doc/device-tree-bindings/exynos/tmu.txt b/doc/device-tree-bindings/exynos/tmu.txt
new file mode 100644 (file)
index 0000000..89d3bf0
--- /dev/null
@@ -0,0 +1,44 @@
+Exynos Thermal management Unit
+
+Required properties:
+
+ - compatible : Should be "samsung,exynos-tmu" for TMU
+ - samsung,min-temp : Minimum temperature value (25 degree celsius)
+       - Current temperature of SoC should be more than this value.
+ - samsung,max-temp : Maximum temperature value (125 degree celsius)
+       - Current temperature of SoC should be less than this value.
+ - samsung,start-warning : Temperature at which TMU starts giving warning (degree celsius)
+ - samsung,start-tripping : Temperature at which TMU shuts down the system (degree celsius)
+ - samsung,hw-tripping : Temperature at which hardware tripping should happen
+       in case TMU fails to power off (degree celsius)
+ - samsung,efuse-min-value : SOC efuse min value (Constant 40)
+       - efuse-value should be more than this value.
+ - samsung,efuse-value : SOC actual efuse value (Literal value)
+       - This is the data trimming info.
+       - This value is used to calculate measuring error.
+ - samsung,efuse-max-value : SoC max efuse value (Constant 100)
+       - efuse-value should be less than this value.
+ - samsung,slope : Default value 274761730 (Constant 0x1060_8802).
+       - This is the default value for TMU_CONTROL register.
+       - It sets the gain of amplifier to the positive-tc generator block.
+       - It selects thermal tripping mode and enables thermal tripping.
+ - samsung,dc-value : Measured data calibration value (Constant 25)
+       - Used for tempearture calculation.
+       - This is 25 because temperature measured is always above 25 degrees.
+
+
+Example:
+
+tmu@10060000 {
+       compatible = "samsung,exynos-tmu"
+       samsung,min-temp = <25>;
+       samsung,max-temp = <125>;
+       samsung,start-warning = <95>;
+       samsung,start-tripping = <105>;
+       samsung,hw-tripping = <110>;
+       samsung,efuse-min-value = <40>;
+       samsung,efuse-value = <55>;
+       samsung,efuse-max-value = <100>;
+       samsung,slope = <274761730>;
+       samsung,dc-value = <25>;
+};
index 65791aa..1d6faa2 100644 (file)
@@ -43,6 +43,7 @@ COBJS-$(CONFIG_MXS_MMC) += mxsmmc.o
 COBJS-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o
 COBJS-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o
 COBJS-$(CONFIG_SDHCI) += sdhci.o
+COBJS-$(CONFIG_BCM2835_SDHCI) += bcm2835_sdhci.o
 COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
 COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
 COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o
diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c
new file mode 100644 (file)
index 0000000..b0afc3c
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * This code was extracted from:
+ * git://github.com/gonzoua/u-boot-pi.git master
+ * and hence presumably (C) 2012 Oleksandr Tymoshenko
+ *
+ * Tweaks for U-Boot upstreaming
+ * (C) 2012 Stephen Warren
+ *
+ * Portions (e.g. read/write macros, concepts for back-to-back register write
+ * timing workarounds) obviously extracted from the Linux kernel at:
+ * https://github.com/raspberrypi/linux.git rpi-3.6.y
+ *
+ * The Linux kernel code has the following (c) and license, which is hence
+ * propagated to Oleksandr's tree and here:
+ *
+ * Support for SDHCI device on 2835
+ * Based on sdhci-bcm2708.c (c) 2010 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * SDHCI platform device - Arasan SD controller in BCM2708
+ *
+ * Inspired by sdhci-pci.c, by Pierre Ossman
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <sdhci.h>
+
+/* 400KHz is max freq for card ID etc. Use that as min */
+#define MIN_FREQ 400000
+
+struct bcm2835_sdhci_host {
+       struct sdhci_host host;
+       uint twoticks_delay;
+       ulong last_write;
+};
+
+static inline struct bcm2835_sdhci_host *to_bcm(struct sdhci_host *host)
+{
+       return (struct bcm2835_sdhci_host *)host;
+}
+
+static inline void bcm2835_sdhci_raw_writel(struct sdhci_host *host, u32 val,
+                                               int reg)
+{
+       struct bcm2835_sdhci_host *bcm_host = to_bcm(host);
+
+       /*
+        * The Arasan has a bugette whereby it may lose the content of
+        * successive writes to registers that are within two SD-card clock
+        * cycles of each other (a clock domain crossing problem).
+        * It seems, however, that the data register does not have this problem.
+        * (Which is just as well - otherwise we'd have to nobble the DMA engine
+        * too)
+        */
+       while (get_timer(bcm_host->last_write) < bcm_host->twoticks_delay)
+               ;
+
+       writel(val, host->ioaddr + reg);
+       bcm_host->last_write = get_timer(0);
+}
+
+static inline u32 bcm2835_sdhci_raw_readl(struct sdhci_host *host, int reg)
+{
+       return readl(host->ioaddr + reg);
+}
+
+static void bcm2835_sdhci_writel(struct sdhci_host *host, u32 val, int reg)
+{
+       bcm2835_sdhci_raw_writel(host, val, reg);
+}
+
+static void bcm2835_sdhci_writew(struct sdhci_host *host, u16 val, int reg)
+{
+       static u32 shadow;
+       u32 oldval = (reg == SDHCI_COMMAND) ? shadow :
+               bcm2835_sdhci_raw_readl(host, reg & ~3);
+       u32 word_num = (reg >> 1) & 1;
+       u32 word_shift = word_num * 16;
+       u32 mask = 0xffff << word_shift;
+       u32 newval = (oldval & ~mask) | (val << word_shift);
+
+       if (reg == SDHCI_TRANSFER_MODE)
+               shadow = newval;
+       else
+               bcm2835_sdhci_raw_writel(host, newval, reg & ~3);
+}
+
+static void bcm2835_sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+       u32 oldval = bcm2835_sdhci_raw_readl(host, reg & ~3);
+       u32 byte_num = reg & 3;
+       u32 byte_shift = byte_num * 8;
+       u32 mask = 0xff << byte_shift;
+       u32 newval = (oldval & ~mask) | (val << byte_shift);
+
+       bcm2835_sdhci_raw_writel(host, newval, reg & ~3);
+}
+
+static u32 bcm2835_sdhci_readl(struct sdhci_host *host, int reg)
+{
+       u32 val = bcm2835_sdhci_raw_readl(host, reg);
+
+       return val;
+}
+
+static u16 bcm2835_sdhci_readw(struct sdhci_host *host, int reg)
+{
+       u32 val = bcm2835_sdhci_raw_readl(host, (reg & ~3));
+       u32 word_num = (reg >> 1) & 1;
+       u32 word_shift = word_num * 16;
+       u32 word = (val >> word_shift) & 0xffff;
+
+       return word;
+}
+
+static u8 bcm2835_sdhci_readb(struct sdhci_host *host, int reg)
+{
+       u32 val = bcm2835_sdhci_raw_readl(host, (reg & ~3));
+       u32 byte_num = reg & 3;
+       u32 byte_shift = byte_num * 8;
+       u32 byte = (val >> byte_shift) & 0xff;
+
+       return byte;
+}
+
+static const struct sdhci_ops bcm2835_ops = {
+       .write_l = bcm2835_sdhci_writel,
+       .write_w = bcm2835_sdhci_writew,
+       .write_b = bcm2835_sdhci_writeb,
+       .read_l = bcm2835_sdhci_readl,
+       .read_w = bcm2835_sdhci_readw,
+       .read_b = bcm2835_sdhci_readb,
+};
+
+int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq)
+{
+       struct bcm2835_sdhci_host *bcm_host;
+       struct sdhci_host *host;
+
+       bcm_host = malloc(sizeof(*bcm_host));
+       if (!bcm_host) {
+               printf("sdhci_host malloc fail!\n");
+               return 1;
+       }
+
+       /*
+        * See the comments in bcm2835_sdhci_raw_writel().
+        *
+        * This should probably be dynamically calculated based on the actual
+        * frequency. However, this is the longest we'll have to wait, and
+        * doesn't seem to slow access down too much, so the added complexity
+        * doesn't seem worth it for now.
+        *
+        * 1/MIN_FREQ is (max) time per tick of eMMC clock.
+        * 2/MIN_FREQ is time for two ticks.
+        * Multiply by 1000000 to get uS per two ticks.
+        * +1 for hack rounding.
+        */
+       bcm_host->twoticks_delay = ((2 * 1000000) / MIN_FREQ) + 1;
+       bcm_host->last_write = 0;
+
+       host = &bcm_host->host;
+       host->name = "bcm2835_sdhci";
+       host->ioaddr = (void *)regbase;
+       host->quirks = SDHCI_QUIRK_BROKEN_VOLTAGE | SDHCI_QUIRK_BROKEN_R1B |
+               SDHCI_QUIRK_WAIT_SEND_CMD;
+       host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+       host->ops = &bcm2835_ops;
+
+       host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
+       add_sdhci(host, emmc_freq, MIN_FREQ);
+
+       return 0;
+}
index 7b5fdd9..d732581 100644 (file)
@@ -51,8 +51,12 @@ int mmc_getwp(struct mmc *mmc)
 
        wp = board_mmc_getwp(mmc);
 
-       if ((wp < 0) && mmc->getwp)
-               wp = mmc->getwp(mmc);
+       if (wp < 0) {
+               if (mmc->getwp)
+                       wp = mmc->getwp(mmc);
+               else
+                       wp = 0;
+       }
 
        return wp;
 }
@@ -692,8 +696,12 @@ int mmc_getcd(struct mmc *mmc)
 
        cd = board_mmc_getcd(mmc);
 
-       if ((cd < 0) && mmc->getcd)
-               cd = mmc->getcd(mmc);
+       if (cd < 0) {
+               if (mmc->getcd)
+                       cd = mmc->getcd(mmc);
+               else
+                       cd = 1;
+       }
 
        return cd;
 }
index 67cfcc2..166744c 100644 (file)
@@ -593,8 +593,6 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
        mmc->send_cmd = mmc_send_cmd;
        mmc->set_ios = mmc_set_ios;
        mmc->init = mmc_init_setup;
-       mmc->getcd = omap_mmc_getcd;
-       mmc->getwp = omap_mmc_getwp;
        mmc->priv = priv_data;
 
        switch (dev_index) {
@@ -616,7 +614,13 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
                return 1;
        }
        priv_data->cd_gpio = omap_mmc_setup_gpio_in(cd_gpio, "mmc_cd");
+       if (priv_data->cd_gpio != -1)
+               mmc->getcd = omap_mmc_getcd;
+
        priv_data->wp_gpio = omap_mmc_setup_gpio_in(wp_gpio, "mmc_wp");
+       if (priv_data->wp_gpio != -1)
+               mmc->getwp = omap_mmc_getwp;
+
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
        mmc->host_caps = (MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
                                MMC_MODE_HC) & ~host_caps_mask;
index daca0ea..1eaea04 100644 (file)
@@ -412,9 +412,11 @@ int sdhci_init(struct mmc *mmc)
                        status = sdhci_readl(host, SDHCI_PRESENT_STATE);
        }
 
-       /* Eable all state */
-       sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_ENABLE);
-       sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_SIGNAL_ENABLE);
+       /* Enable only interrupts served by the SD controller */
+       sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK
+                    , SDHCI_INT_ENABLE);
+       /* Mask all sdhci interrupt sources */
+       sdhci_writel(host, 0x0, SDHCI_SIGNAL_ENABLE);
 
        return 0;
 }
index cee394e..bbf5443 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/io.h>
 #include <asm/errno.h>
 #include <asm/arch/mem.h>
+#include <asm/arch/cpu.h>
 #include <asm/arch/omap_gpmc.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/compiler.h>
index 05dc644..2716209 100644 (file)
@@ -67,6 +67,11 @@ static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
                .nr_blocks              = 128,
                .name                   = "W25Q80",
        },
+       {
+               .id                     = 0x6016,
+               .nr_blocks              = 512,
+               .name                   = "W25Q32DW",
+       },
        {
                .id                     = 0x6017,
                .nr_blocks              = 128,
index 93f8417..7a36850 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <phy.h>
+#include <asm/arch/cpu.h>
 
 #define BITMASK(bits)          (BIT(bits) - 1)
 #define PHY_REG_MASK           0x1f
index 8c71901..1dac16a 100644 (file)
@@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk
 
 LIB    := $(obj)libpower.o
 
+COBJS-$(CONFIG_EXYNOS_TMU)     += exynos-tmu.o
 COBJS-$(CONFIG_FTPMU010_POWER) += ftpmu010.o
 COBJS-$(CONFIG_TPS6586X_POWER) += tps6586x.o
 COBJS-$(CONFIG_TWL4030_POWER)  += twl4030.o
diff --git a/drivers/power/exynos-tmu.c b/drivers/power/exynos-tmu.c
new file mode 100644 (file)
index 0000000..d4b3e65
--- /dev/null
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *      http://www.samsung.com
+ * Akshay Saraswat <akshay.s@samsung.com>
+ *
+ * EXYNOS - Thermal Management Unit
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ * 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 <errno.h>
+#include <fdtdec.h>
+#include <tmu.h>
+#include <asm/arch/tmu.h>
+#include <asm/arch/power.h>
+
+#define TRIMINFO_RELOAD                1
+#define CORE_EN                        1
+#define THERM_TRIP_EN          (1 << 12)
+
+#define INTEN_RISE0            1
+#define INTEN_RISE1            (1 << 4)
+#define INTEN_RISE2            (1 << 8)
+#define INTEN_FALL0            (1 << 16)
+#define INTEN_FALL1            (1 << 20)
+#define INTEN_FALL2            (1 << 24)
+
+#define TRIM_INFO_MASK         0xff
+
+#define INTCLEAR_RISE0         1
+#define INTCLEAR_RISE1         (1 << 4)
+#define INTCLEAR_RISE2         (1 << 8)
+#define INTCLEAR_FALL0         (1 << 16)
+#define INTCLEAR_FALL1         (1 << 20)
+#define INTCLEAR_FALL2         (1 << 24)
+#define INTCLEARALL            (INTCLEAR_RISE0 | INTCLEAR_RISE1 | \
+                                INTCLEAR_RISE2 | INTCLEAR_FALL0 | \
+                                INTCLEAR_FALL1 | INTCLEAR_FALL2)
+
+/* Tmeperature threshold values for various thermal events */
+struct temperature_params {
+       /* minimum value in temperature code range */
+       unsigned int min_val;
+       /* maximum value in temperature code range */
+       unsigned int max_val;
+       /* temperature threshold to start warning */
+       unsigned int start_warning;
+       /* temperature threshold CPU tripping */
+       unsigned int start_tripping;
+       /* temperature threshold for HW tripping */
+       unsigned int hardware_tripping;
+};
+
+/* Pre-defined values and thresholds for calibration of current temperature */
+struct tmu_data {
+       /* pre-defined temperature thresholds */
+       struct temperature_params ts;
+       /* pre-defined efuse range minimum value */
+       unsigned int efuse_min_value;
+       /* pre-defined efuse value for temperature calibration */
+       unsigned int efuse_value;
+       /* pre-defined efuse range maximum value */
+       unsigned int efuse_max_value;
+       /* current temperature sensing slope */
+       unsigned int slope;
+};
+
+/* TMU device specific details and status */
+struct tmu_info {
+       /* base Address for the TMU */
+       unsigned tmu_base;
+       /* pre-defined values for calibration and thresholds */
+       struct tmu_data data;
+       /* value required for triminfo_25 calibration */
+       unsigned int te1;
+       /* value required for triminfo_85 calibration */
+       unsigned int te2;
+       /* Value for measured data calibration */
+       int dc_value;
+       /* enum value indicating status of the TMU */
+       int tmu_state;
+};
+
+/* Global struct tmu_info variable to store init values */
+static struct tmu_info gbl_info;
+
+/*
+ * Get current temperature code from register,
+ * then calculate and calibrate it's value
+ * in degree celsius.
+ *
+ * @return     current temperature of the chip as sensed by TMU
+ */
+static int get_cur_temp(struct tmu_info *info)
+{
+       int cur_temp;
+       struct exynos5_tmu_reg *reg = (struct exynos5_tmu_reg *)info->tmu_base;
+
+       /*
+        * Temperature code range between min 25 and max 125.
+        * May run more than once for first call as initial sensing
+        * has not yet happened.
+        */
+       do {
+               cur_temp = readl(&reg->current_temp) & 0xff;
+       } while (cur_temp == 0 && info->tmu_state == TMU_STATUS_NORMAL);
+
+       /* Calibrate current temperature */
+       cur_temp = cur_temp - info->te1 + info->dc_value;
+
+       return cur_temp;
+}
+
+/*
+ * Monitors status of the TMU device and exynos temperature
+ *
+ * @param temp pointer to the current temperature value
+ * @return     enum tmu_status_t value, code indicating event to execute
+ */
+enum tmu_status_t tmu_monitor(int *temp)
+{
+       int cur_temp;
+       struct tmu_data *data = &gbl_info.data;
+
+       if (gbl_info.tmu_state == TMU_STATUS_INIT)
+               return TMU_STATUS_INIT;
+
+       /* Read current temperature of the SOC */
+       cur_temp = get_cur_temp(&gbl_info);
+       *temp = cur_temp;
+
+       /* Temperature code lies between min 25 and max 125 */
+       if (cur_temp >= data->ts.start_tripping &&
+                       cur_temp <= data->ts.max_val) {
+               return TMU_STATUS_TRIPPED;
+       } else if (cur_temp >= data->ts.start_warning) {
+               return TMU_STATUS_WARNING;
+       } else if (cur_temp < data->ts.start_warning &&
+                       cur_temp >= data->ts.min_val) {
+               return TMU_STATUS_NORMAL;
+       } else {
+               /* Temperature code does not lie between min 25 and max 125 */
+               gbl_info.tmu_state = TMU_STATUS_INIT;
+               debug("EXYNOS_TMU: Thermal reading failed\n");
+               return TMU_STATUS_INIT;
+       }
+}
+
+/*
+ * Get TMU specific pre-defined values from FDT
+ *
+ * @param info pointer to the tmu_info struct
+ * @param blob  FDT blob
+ * @return     int value, 0 for success
+ */
+static int get_tmu_fdt_values(struct tmu_info *info, const void *blob)
+{
+#ifdef CONFIG_OF_CONTROL
+       int node;
+       int error = 0;
+
+       /* Get the node from FDT for TMU */
+       node = fdtdec_next_compatible(blob, 0,
+                                     COMPAT_SAMSUNG_EXYNOS_TMU);
+       if (node < 0) {
+               debug("EXYNOS_TMU: No node for tmu in device tree\n");
+               return -1;
+       }
+
+       /*
+        * Get the pre-defined TMU specific values from FDT.
+        * All of these are expected to be correct otherwise
+        * miscalculation of register values in tmu_setup_parameters
+        * may result in misleading current temperature.
+        */
+       info->tmu_base = fdtdec_get_addr(blob, node, "reg");
+       if (info->tmu_base == FDT_ADDR_T_NONE) {
+               debug("%s: Missing tmu-base\n", __func__);
+               return -1;
+       }
+       info->data.ts.min_val = fdtdec_get_int(blob,
+                               node, "samsung,min-temp", -1);
+       error |= info->data.ts.min_val;
+       info->data.ts.max_val = fdtdec_get_int(blob,
+                               node, "samsung,max-temp", -1);
+       error |= info->data.ts.max_val;
+       info->data.ts.start_warning = fdtdec_get_int(blob,
+                               node, "samsung,start-warning", -1);
+       error |= info->data.ts.start_warning;
+       info->data.ts.start_tripping = fdtdec_get_int(blob,
+                               node, "samsung,start-tripping", -1);
+       error |= info->data.ts.start_tripping;
+       info->data.ts.hardware_tripping = fdtdec_get_int(blob,
+                               node, "samsung,hw-tripping", -1);
+       error |= info->data.ts.hardware_tripping;
+       info->data.efuse_min_value = fdtdec_get_int(blob,
+                               node, "samsung,efuse-min-value", -1);
+       error |= info->data.efuse_min_value;
+       info->data.efuse_value = fdtdec_get_int(blob,
+                               node, "samsung,efuse-value", -1);
+       error |= info->data.efuse_value;
+       info->data.efuse_max_value = fdtdec_get_int(blob,
+                               node, "samsung,efuse-max-value", -1);
+       error |= info->data.efuse_max_value;
+       info->data.slope = fdtdec_get_int(blob,
+                               node, "samsung,slope", -1);
+       error |= info->data.slope;
+       info->dc_value = fdtdec_get_int(blob,
+                               node, "samsung,dc-value", -1);
+       error |= info->dc_value;
+
+       if (error == -1) {
+               debug("fail to get tmu node properties\n");
+               return -1;
+       }
+#endif
+
+       return 0;
+}
+
+/*
+ * Calibrate and calculate threshold values and
+ * enable interrupt levels
+ *
+ * @param      info pointer to the tmu_info struct
+ */
+static void tmu_setup_parameters(struct tmu_info *info)
+{
+       unsigned int te_code, con;
+       unsigned int warning_code, trip_code, hwtrip_code;
+       unsigned int cooling_temp;
+       unsigned int rising_value;
+       struct tmu_data *data = &info->data;
+       struct exynos5_tmu_reg *reg = (struct exynos5_tmu_reg *)info->tmu_base;
+
+       /* Must reload for reading efuse value from triminfo register */
+       writel(TRIMINFO_RELOAD, &reg->triminfo_control);
+
+       /* Get the compensation parameter */
+       te_code = readl(&reg->triminfo);
+       info->te1 = te_code & TRIM_INFO_MASK;
+       info->te2 = ((te_code >> 8) & TRIM_INFO_MASK);
+
+       if ((data->efuse_min_value > info->te1) ||
+                       (info->te1 > data->efuse_max_value)
+                       ||  (info->te2 != 0))
+               info->te1 = data->efuse_value;
+
+       /* Get RISING & FALLING Threshold value */
+       warning_code = data->ts.start_warning
+                       + info->te1 - info->dc_value;
+       trip_code = data->ts.start_tripping
+                       + info->te1 - info->dc_value;
+       hwtrip_code = data->ts.hardware_tripping
+                       + info->te1 - info->dc_value;
+
+       cooling_temp = 0;
+
+       rising_value = ((warning_code << 8) |
+                       (trip_code << 16) |
+                       (hwtrip_code << 24));
+
+       /* Set interrupt level */
+       writel(rising_value, &reg->threshold_temp_rise);
+       writel(cooling_temp, &reg->threshold_temp_fall);
+
+       /*
+        * Init TMU control tuning parameters
+        * [28:24] VREF - Voltage reference
+        * [15:13] THERM_TRIP_MODE - Tripping mode
+        * [12] THERM_TRIP_EN - Thermal tripping enable
+        * [11:8] BUF_SLOPE_SEL - Gain of amplifier
+        * [6] THERM_TRIP_BY_TQ_EN - Tripping by TQ pin
+        */
+       writel(data->slope, &reg->tmu_control);
+
+       writel(INTCLEARALL, &reg->intclear);
+
+       /* TMU core enable */
+       con = readl(&reg->tmu_control);
+       con |= THERM_TRIP_EN | CORE_EN;
+
+       writel(con, &reg->tmu_control);
+
+       /* Enable HW thermal trip */
+       set_hw_thermal_trip();
+
+       /* LEV1 LEV2 interrupt enable */
+       writel(INTEN_RISE1 | INTEN_RISE2, &reg->inten);
+}
+
+/*
+ * Initialize TMU device
+ *
+ * @param blob  FDT blob
+ * @return     int value, 0 for success
+ */
+int tmu_init(const void *blob)
+{
+       gbl_info.tmu_state = TMU_STATUS_INIT;
+       if (get_tmu_fdt_values(&gbl_info, blob) < 0)
+               goto ret;
+
+       tmu_setup_parameters(&gbl_info);
+       gbl_info.tmu_state = TMU_STATUS_NORMAL;
+ret:
+
+       return gbl_info.tmu_state;
+}
index b2da8b3..ed4e6b3 100644 (file)
@@ -43,7 +43,7 @@ void NS16550_init(NS16550_t com_port, int baud_divisor)
 
        serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier);
 #if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || \
-                                       defined(CONFIG_AM33XX)
+                       defined(CONFIG_AM33XX) || defined(CONFIG_TI814X)
        serial_out(0x7, &com_port->mdr1);       /* mode select reset TL16C750*/
 #endif
        serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
@@ -57,7 +57,8 @@ void NS16550_init(NS16550_t com_port, int baud_divisor)
        serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
        serial_out(UART_LCRVAL, &com_port->lcr);
 #if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || \
-       defined(CONFIG_AM33XX) || defined(CONFIG_SOC_DA8XX)
+       defined(CONFIG_AM33XX) || defined(CONFIG_SOC_DA8XX) || \
+       defined(CONFIG_TI814X)
 
 #if defined(CONFIG_APTIX)
        /* /13 mode so Aptix 6MHz can hit 115200 */
index 8fdffb1..1987ca1 100644 (file)
@@ -28,6 +28,7 @@ LIB   := $(obj)libsound.o
 COBJS-$(CONFIG_SOUND)  += sound.o
 COBJS-$(CONFIG_I2S)    += samsung-i2s.o
 COBJS-$(CONFIG_SOUND_WM8994)   += wm8994.o
+COBJS-$(CONFIG_SOUND_MAX98095) += max98095.o
 
 COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
diff --git a/drivers/sound/max98095.c b/drivers/sound/max98095.c
new file mode 100644 (file)
index 0000000..d69db58
--- /dev/null
@@ -0,0 +1,550 @@
+/*
+ * max98095.c -- MAX98095 ALSA SoC Audio driver
+ *
+ * Copyright 2011 Maxim Integrated Products
+ *
+ * Modified for uboot by R. Chandrasekar (rcsekar@samsung.com)
+ *
+ * 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.
+ */
+#include <asm/arch/clk.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/power.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <common.h>
+#include <div64.h>
+#include <fdtdec.h>
+#include <i2c.h>
+#include <sound.h>
+#include "i2s.h"
+#include "max98095.h"
+
+enum max98095_type {
+       MAX98095,
+};
+
+struct max98095_priv {
+       enum max98095_type devtype;
+       unsigned int sysclk;
+       unsigned int rate;
+       unsigned int fmt;
+};
+
+static struct sound_codec_info g_codec_info;
+struct max98095_priv g_max98095_info;
+unsigned int g_max98095_i2c_dev_addr;
+
+/* Index 0 is reserved. */
+int rate_table[] = {0, 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000,
+               88200, 96000};
+
+/*
+ * Writes value to a device register through i2c
+ *
+ * @param reg  reg number to be write
+ * @param data data to be writen to the above registor
+ *
+ * @return     int value 1 for change, 0 for no change or negative error code.
+ */
+static int max98095_i2c_write(unsigned int reg, unsigned char data)
+{
+       debug("%s: Write Addr : 0x%02X, Data :  0x%02X\n",
+               __func__, reg, data);
+       return i2c_write(g_max98095_i2c_dev_addr, reg, 1, &data, 1);
+}
+
+/*
+ * Read a value from a device register through i2c
+ *
+ * @param reg  reg number to be read
+ * @param data address of read data to be stored
+ *
+ * @return     int value 0 for success, -1 in case of error.
+ */
+static unsigned int max98095_i2c_read(unsigned int reg, unsigned char *data)
+{
+       int ret;
+
+       ret = i2c_read(g_max98095_i2c_dev_addr, reg, 1, data, 1);
+       if (ret != 0) {
+               debug("%s: Error while reading register %#04x\n",
+                       __func__, reg);
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+ * update device register bits through i2c
+ *
+ * @param reg  codec register
+ * @param mask register mask
+ * @param value        new value
+ *
+ * @return int value 0 for success, non-zero error code.
+ */
+static int max98095_update_bits(unsigned int reg, unsigned char mask,
+                               unsigned char value)
+{
+       int change, ret = 0;
+       unsigned char old, new;
+
+       if (max98095_i2c_read(reg, &old) != 0)
+               return -1;
+       new = (old & ~mask) | (value & mask);
+       change  = (old != new) ? 1 : 0;
+       if (change)
+               ret = max98095_i2c_write(reg, new);
+       if (ret < 0)
+               return ret;
+
+       return change;
+}
+
+/*
+ * codec mclk clock divider coefficients based on sampling rate
+ *
+ * @param rate sampling rate
+ * @param value address of indexvalue to be stored
+ *
+ * @return     0 for success or negative error code.
+ */
+static int rate_value(int rate, u8 *value)
+{
+       int i;
+
+       for (i = 1; i < ARRAY_SIZE(rate_table); i++) {
+               if (rate_table[i] >= rate) {
+                       *value = i;
+                       return 0;
+               }
+       }
+       *value = 1;
+
+       return -1;
+}
+
+/*
+ * Sets hw params for max98095
+ *
+ * @param max98095     max98095 information pointer
+ * @param rate         Sampling rate
+ * @param bits_per_sample      Bits per sample
+ *
+ * @return -1 for error  and 0  Success.
+ */
+static int max98095_hw_params(struct max98095_priv *max98095,
+               unsigned int rate, unsigned int bits_per_sample)
+{
+       u8 regval;
+       int error;
+
+       switch (bits_per_sample) {
+       case 16:
+               error = max98095_update_bits(M98095_034_DAI2_FORMAT,
+                       M98095_DAI_WS, 0);
+               break;
+       case 24:
+               error = max98095_update_bits(M98095_034_DAI2_FORMAT,
+                       M98095_DAI_WS, M98095_DAI_WS);
+               break;
+       default:
+               debug("%s: Illegal bits per sample %d.\n",
+                       __func__, bits_per_sample);
+               return -1;
+       }
+
+       if (rate_value(rate, &regval)) {
+               debug("%s: Failed to set sample rate to %d.\n",
+                       __func__, rate);
+               return -1;
+       }
+       max98095->rate = rate;
+
+       error |= max98095_update_bits(M98095_031_DAI2_CLKMODE,
+               M98095_CLKMODE_MASK, regval);
+
+       /* Update sample rate mode */
+       if (rate < 50000)
+               error |= max98095_update_bits(M98095_038_DAI2_FILTERS,
+                       M98095_DAI_DHF, 0);
+       else
+               error |= max98095_update_bits(M98095_038_DAI2_FILTERS,
+                       M98095_DAI_DHF, M98095_DAI_DHF);
+
+       if (error < 0) {
+               debug("%s: Error setting hardware params.\n", __func__);
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+ * Configures Audio interface system clock for the given frequency
+ *
+ * @param max98095     max98095 information
+ * @param freq         Sampling frequency in Hz
+ *
+ * @return -1 for error and 0 success.
+ */
+static int max98095_set_sysclk(struct max98095_priv *max98095,
+                               unsigned int freq)
+{
+       int error = 0;
+
+       /* Requested clock frequency is already setup */
+       if (freq == max98095->sysclk)
+               return 0;
+
+       /* Setup clocks for slave mode, and using the PLL
+        * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
+        *      0x02 (when master clk is 20MHz to 40MHz)..
+        *      0x03 (when master clk is 40MHz to 60MHz)..
+        */
+       if ((freq >= 10000000) && (freq < 20000000)) {
+               error = max98095_i2c_write(M98095_026_SYS_CLK, 0x10);
+       } else if ((freq >= 20000000) && (freq < 40000000)) {
+               error = max98095_i2c_write(M98095_026_SYS_CLK, 0x20);
+       } else if ((freq >= 40000000) && (freq < 60000000)) {
+               error = max98095_i2c_write(M98095_026_SYS_CLK, 0x30);
+       } else {
+               debug("%s: Invalid master clock frequency\n", __func__);
+               return -1;
+       }
+
+       debug("%s: Clock at %uHz\n", __func__, freq);
+
+       if (error < 0)
+               return -1;
+
+       max98095->sysclk = freq;
+       return 0;
+}
+
+/*
+ * Sets Max98095 I2S format
+ *
+ * @param max98095     max98095 information
+ * @param fmt          i2S format - supports a subset of the options defined
+ *                     in i2s.h.
+ *
+ * @return -1 for error and 0  Success.
+ */
+static int max98095_set_fmt(struct max98095_priv *max98095, int fmt)
+{
+       u8 regval = 0;
+       int error = 0;
+
+       if (fmt == max98095->fmt)
+               return 0;
+
+       max98095->fmt = fmt;
+
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBS_CFS:
+               /* Slave mode PLL */
+               error |= max98095_i2c_write(M98095_032_DAI2_CLKCFG_HI,
+                                       0x80);
+               error |= max98095_i2c_write(M98095_033_DAI2_CLKCFG_LO,
+                                       0x00);
+               break;
+       case SND_SOC_DAIFMT_CBM_CFM:
+               /* Set to master mode */
+               regval |= M98095_DAI_MAS;
+               break;
+       case SND_SOC_DAIFMT_CBS_CFM:
+       case SND_SOC_DAIFMT_CBM_CFS:
+       default:
+               debug("%s: Clock mode unsupported\n", __func__);
+               return -1;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               regval |= M98095_DAI_DLY;
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               break;
+       default:
+               debug("%s: Unrecognized format.\n", __func__);
+               return -1;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_NB_NF:
+               break;
+       case SND_SOC_DAIFMT_NB_IF:
+               regval |= M98095_DAI_WCI;
+               break;
+       case SND_SOC_DAIFMT_IB_NF:
+               regval |= M98095_DAI_BCI;
+               break;
+       case SND_SOC_DAIFMT_IB_IF:
+               regval |= M98095_DAI_BCI | M98095_DAI_WCI;
+               break;
+       default:
+               debug("%s: Unrecognized inversion settings.\n", __func__);
+               return -1;
+       }
+
+       error |= max98095_update_bits(M98095_034_DAI2_FORMAT,
+               M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
+               M98095_DAI_WCI, regval);
+
+       error |= max98095_i2c_write(M98095_035_DAI2_CLOCK,
+               M98095_DAI_BSEL64);
+
+       if (error < 0) {
+               debug("%s: Error setting i2s format.\n", __func__);
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+ * resets the audio codec
+ *
+ * @return -1 for error and 0 success.
+ */
+static int max98095_reset(void)
+{
+       int i, ret;
+
+       /*
+        * Gracefully reset the DSP core and the codec hardware in a proper
+        * sequence.
+        */
+       ret = max98095_i2c_write(M98095_00F_HOST_CFG, 0);
+       if (ret != 0) {
+               debug("%s: Failed to reset DSP: %d\n", __func__, ret);
+               return ret;
+       }
+
+       ret = max98095_i2c_write(M98095_097_PWR_SYS, 0);
+       if (ret != 0) {
+               debug("%s: Failed to reset codec: %d\n", __func__, ret);
+               return ret;
+       }
+
+       /*
+        * Reset to hardware default for registers, as there is not a soft
+        * reset hardware control register.
+        */
+       for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) {
+               ret = max98095_i2c_write(i, 0);
+               if (ret < 0) {
+                       debug("%s: Failed to reset: %d\n", __func__, ret);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Intialise max98095 codec device
+ *
+ * @param max98095     max98095 information
+ *
+ * @returns -1 for error  and 0 Success.
+ */
+static int max98095_device_init(struct max98095_priv *max98095)
+{
+       unsigned char id;
+       int error = 0;
+
+       /* reset the codec, the DSP core, and disable all interrupts */
+       error = max98095_reset();
+       if (error != 0) {
+               debug("Reset\n");
+               return error;
+       }
+
+       /* initialize private data */
+       max98095->sysclk = -1U;
+       max98095->rate = -1U;
+       max98095->fmt = -1U;
+
+       error = max98095_i2c_read(M98095_0FF_REV_ID, &id);
+       if (error < 0) {
+               debug("%s: Failure reading hardware revision: %d\n",
+                       __func__, id);
+               goto err_access;
+       }
+       debug("%s: Hardware revision: %c\n", __func__, (id - 0x40) + 'A');
+
+       error |= max98095_i2c_write(M98095_097_PWR_SYS, M98095_PWRSV);
+
+       /*
+        * initialize registers to hardware default configuring audio
+        * interface2 to DAC
+        */
+       error |= max98095_i2c_write(M98095_048_MIX_DAC_LR,
+               M98095_DAI2M_TO_DACL|M98095_DAI2M_TO_DACR);
+
+       error |= max98095_i2c_write(M98095_092_PWR_EN_OUT,
+                       M98095_SPK_SPREADSPECTRUM);
+       error |= max98095_i2c_write(M98095_045_CFG_DSP, M98095_DSPNORMAL);
+       error |= max98095_i2c_write(M98095_04E_CFG_HP, M98095_HPNORMAL);
+
+       error |= max98095_i2c_write(M98095_02C_DAI1_IOCFG,
+                       M98095_S1NORMAL|M98095_SDATA);
+
+       error |= max98095_i2c_write(M98095_036_DAI2_IOCFG,
+                       M98095_S2NORMAL|M98095_SDATA);
+
+       error |= max98095_i2c_write(M98095_040_DAI3_IOCFG,
+                       M98095_S3NORMAL|M98095_SDATA);
+
+       /* take the codec out of the shut down */
+       error |= max98095_update_bits(M98095_097_PWR_SYS, M98095_SHDNRUN,
+                       M98095_SHDNRUN);
+       /* route DACL and DACR output to HO and Spekers */
+       error |= max98095_i2c_write(M98095_050_MIX_SPK_LEFT, 0x01); /* DACL */
+       error |= max98095_i2c_write(M98095_051_MIX_SPK_RIGHT, 0x01);/* DACR */
+       error |= max98095_i2c_write(M98095_04C_MIX_HP_LEFT, 0x01);  /* DACL */
+       error |= max98095_i2c_write(M98095_04D_MIX_HP_RIGHT, 0x01); /* DACR */
+
+       /* power Enable */
+       error |= max98095_i2c_write(M98095_091_PWR_EN_OUT, 0xF3);
+
+       /* set Volume */
+       error |= max98095_i2c_write(M98095_064_LVL_HP_L, 15);
+       error |= max98095_i2c_write(M98095_065_LVL_HP_R, 15);
+       error |= max98095_i2c_write(M98095_067_LVL_SPK_L, 16);
+       error |= max98095_i2c_write(M98095_068_LVL_SPK_R, 16);
+
+       /* Enable DAIs */
+       error |= max98095_i2c_write(M98095_093_BIAS_CTRL, 0x30);
+       error |= max98095_i2c_write(M98095_096_PWR_DAC_CK, 0x07);
+
+err_access:
+       if (error < 0)
+               return -1;
+
+       return 0;
+}
+
+static int max98095_do_init(struct sound_codec_info *pcodec_info,
+                       int sampling_rate, int mclk_freq,
+                       int bits_per_sample)
+{
+       int ret = 0;
+
+       /* Enable codec clock */
+       set_xclkout();
+
+       /* shift the device address by 1 for 7 bit addressing */
+       g_max98095_i2c_dev_addr = pcodec_info->i2c_dev_addr >> 1;
+
+       if (pcodec_info->codec_type == CODEC_MAX_98095)
+               g_max98095_info.devtype = MAX98095;
+       else {
+               debug("%s: Codec id [%d] not defined\n", __func__,
+                               pcodec_info->codec_type);
+               return -1;
+       }
+
+       ret = max98095_device_init(&g_max98095_info);
+       if (ret < 0) {
+               debug("%s: max98095 codec chip init failed\n", __func__);
+               return ret;
+       }
+
+       ret = max98095_set_sysclk(&g_max98095_info, mclk_freq);
+       if (ret < 0) {
+               debug("%s: max98095 codec set sys clock failed\n", __func__);
+               return ret;
+       }
+
+       ret = max98095_hw_params(&g_max98095_info, sampling_rate,
+                               bits_per_sample);
+
+       if (ret == 0) {
+               ret = max98095_set_fmt(&g_max98095_info,
+                                       SND_SOC_DAIFMT_I2S |
+                                       SND_SOC_DAIFMT_NB_NF |
+                                       SND_SOC_DAIFMT_CBS_CFS);
+       }
+
+       return ret;
+}
+
+static int get_max98095_codec_values(struct sound_codec_info *pcodec_info,
+                               const void *blob)
+{
+       int error = 0;
+#ifdef CONFIG_OF_CONTROL
+       enum fdt_compat_id compat;
+       int node;
+       int parent;
+
+       /* Get the node from FDT for codec */
+       node = fdtdec_next_compatible(blob, 0, COMPAT_MAXIM_98095_CODEC);
+       if (node <= 0) {
+               debug("EXYNOS_SOUND: No node for codec in device tree\n");
+               debug("node = %d\n", node);
+               return -1;
+       }
+
+       parent = fdt_parent_offset(blob, node);
+       if (parent < 0) {
+               debug("%s: Cannot find node parent\n", __func__);
+               return -1;
+       }
+
+       compat = fdtdec_lookup(blob, parent);
+       switch (compat) {
+       case COMPAT_SAMSUNG_S3C2440_I2C:
+               pcodec_info->i2c_bus = i2c_get_bus_num_fdt(parent);
+               error |= pcodec_info->i2c_bus;
+               debug("i2c bus = %d\n", pcodec_info->i2c_bus);
+               pcodec_info->i2c_dev_addr = fdtdec_get_int(blob, node,
+                                                       "reg", 0);
+               error |= pcodec_info->i2c_dev_addr;
+               debug("i2c dev addr = %x\n", pcodec_info->i2c_dev_addr);
+               break;
+       default:
+               debug("%s: Unknown compat id %d\n", __func__, compat);
+               return -1;
+       }
+#else
+       pcodec_info->i2c_bus = AUDIO_I2C_BUS;
+       pcodec_info->i2c_dev_addr = AUDIO_I2C_REG;
+       debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr);
+#endif
+       pcodec_info->codec_type = CODEC_MAX_98095;
+       if (error == -1) {
+               debug("fail to get max98095 codec node properties\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+/* max98095 Device Initialisation */
+int max98095_init(const void *blob, int sampling_rate, int mclk_freq,
+                       int bits_per_sample)
+{
+       int ret;
+       int old_bus = i2c_get_bus_num();
+       struct sound_codec_info *pcodec_info = &g_codec_info;
+
+       if (get_max98095_codec_values(pcodec_info, blob) < 0) {
+               debug("FDT Codec values failed\n");
+                return -1;
+       }
+
+       i2c_set_bus_num(pcodec_info->i2c_bus);
+       ret = max98095_do_init(pcodec_info, sampling_rate, mclk_freq,
+                               bits_per_sample);
+       i2c_set_bus_num(old_bus);
+
+       return ret;
+}
diff --git a/drivers/sound/max98095.h b/drivers/sound/max98095.h
new file mode 100644 (file)
index 0000000..ae5eb14
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * max98095.h -- MAX98095 ALSA SoC Audio driver
+ *
+ * Copyright 2011 Maxim Integrated Products
+ *
+ * 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.
+ */
+
+#ifndef _MAX98095_H
+#define _MAX98095_H
+
+/*
+ * MAX98095 Registers Definition
+ */
+
+#define M98095_000_HOST_DATA           0x00
+#define M98095_001_HOST_INT_STS                0x01
+#define M98095_002_HOST_RSP_STS                0x02
+#define M98095_003_HOST_CMD_STS                0x03
+#define M98095_004_CODEC_STS           0x04
+#define M98095_005_DAI1_ALC_STS                0x05
+#define M98095_006_DAI2_ALC_STS                0x06
+#define M98095_007_JACK_AUTO_STS       0x07
+#define M98095_008_JACK_MANUAL_STS     0x08
+#define M98095_009_JACK_VBAT_STS       0x09
+#define M98095_00A_ACC_ADC_STS         0x0A
+#define M98095_00B_MIC_NG_AGC_STS      0x0B
+#define M98095_00C_SPK_L_VOLT_STS      0x0C
+#define M98095_00D_SPK_R_VOLT_STS      0x0D
+#define M98095_00E_TEMP_SENSOR_STS     0x0E
+#define M98095_00F_HOST_CFG            0x0F
+#define M98095_010_HOST_INT_CFG                0x10
+#define M98095_011_HOST_INT_EN         0x11
+#define M98095_012_CODEC_INT_EN                0x12
+#define M98095_013_JACK_INT_EN         0x13
+#define M98095_014_JACK_INT_EN         0x14
+#define M98095_015_DEC                 0x15
+#define M98095_016_RESERVED            0x16
+#define M98095_017_RESERVED            0x17
+#define M98095_018_KEYCODE3            0x18
+#define M98095_019_KEYCODE2            0x19
+#define M98095_01A_KEYCODE1            0x1A
+#define M98095_01B_KEYCODE0            0x1B
+#define M98095_01C_OEMCODE1            0x1C
+#define M98095_01D_OEMCODE0            0x1D
+#define M98095_01E_XCFG1               0x1E
+#define M98095_01F_XCFG2               0x1F
+#define M98095_020_XCFG3               0x20
+#define M98095_021_XCFG4               0x21
+#define M98095_022_XCFG5               0x22
+#define M98095_023_XCFG6               0x23
+#define M98095_024_XGPIO               0x24
+#define M98095_025_XCLKCFG             0x25
+#define M98095_026_SYS_CLK             0x26
+#define M98095_027_DAI1_CLKMODE                0x27
+#define M98095_028_DAI1_CLKCFG_HI      0x28
+#define M98095_029_DAI1_CLKCFG_LO      0x29
+#define M98095_02A_DAI1_FORMAT         0x2A
+#define M98095_02B_DAI1_CLOCK          0x2B
+#define M98095_02C_DAI1_IOCFG          0x2C
+#define M98095_02D_DAI1_TDM            0x2D
+#define M98095_02E_DAI1_FILTERS                0x2E
+#define M98095_02F_DAI1_LVL1           0x2F
+#define M98095_030_DAI1_LVL2           0x30
+#define M98095_031_DAI2_CLKMODE                0x31
+#define M98095_032_DAI2_CLKCFG_HI      0x32
+#define M98095_033_DAI2_CLKCFG_LO      0x33
+#define M98095_034_DAI2_FORMAT         0x34
+#define M98095_035_DAI2_CLOCK          0x35
+#define M98095_036_DAI2_IOCFG          0x36
+#define M98095_037_DAI2_TDM            0x37
+#define M98095_038_DAI2_FILTERS                0x38
+#define M98095_039_DAI2_LVL1           0x39
+#define M98095_03A_DAI2_LVL2           0x3A
+#define M98095_03B_DAI3_CLKMODE                0x3B
+#define M98095_03C_DAI3_CLKCFG_HI      0x3C
+#define M98095_03D_DAI3_CLKCFG_LO      0x3D
+#define M98095_03E_DAI3_FORMAT         0x3E
+#define M98095_03F_DAI3_CLOCK          0x3F
+#define M98095_040_DAI3_IOCFG          0x40
+#define M98095_041_DAI3_TDM            0x41
+#define M98095_042_DAI3_FILTERS                0x42
+#define M98095_043_DAI3_LVL1           0x43
+#define M98095_044_DAI3_LVL2           0x44
+#define M98095_045_CFG_DSP             0x45
+#define M98095_046_DAC_CTRL1           0x46
+#define M98095_047_DAC_CTRL2           0x47
+#define M98095_048_MIX_DAC_LR          0x48
+#define M98095_049_MIX_DAC_M           0x49
+#define M98095_04A_MIX_ADC_LEFT                0x4A
+#define M98095_04B_MIX_ADC_RIGHT       0x4B
+#define M98095_04C_MIX_HP_LEFT         0x4C
+#define M98095_04D_MIX_HP_RIGHT                0x4D
+#define M98095_04E_CFG_HP              0x4E
+#define M98095_04F_MIX_RCV             0x4F
+#define M98095_050_MIX_SPK_LEFT                0x50
+#define M98095_051_MIX_SPK_RIGHT       0x51
+#define M98095_052_MIX_SPK_CFG         0x52
+#define M98095_053_MIX_LINEOUT1                0x53
+#define M98095_054_MIX_LINEOUT2                0x54
+#define M98095_055_MIX_LINEOUT_CFG     0x55
+#define M98095_056_LVL_SIDETONE_DAI12  0x56
+#define M98095_057_LVL_SIDETONE_DAI3   0x57
+#define M98095_058_LVL_DAI1_PLAY       0x58
+#define M98095_059_LVL_DAI1_EQ         0x59
+#define M98095_05A_LVL_DAI2_PLAY       0x5A
+#define M98095_05B_LVL_DAI2_EQ         0x5B
+#define M98095_05C_LVL_DAI3_PLAY       0x5C
+#define M98095_05D_LVL_ADC_L           0x5D
+#define M98095_05E_LVL_ADC_R           0x5E
+#define M98095_05F_LVL_MIC1            0x5F
+#define M98095_060_LVL_MIC2            0x60
+#define M98095_061_LVL_LINEIN          0x61
+#define M98095_062_LVL_LINEOUT1                0x62
+#define M98095_063_LVL_LINEOUT2                0x63
+#define M98095_064_LVL_HP_L            0x64
+#define M98095_065_LVL_HP_R            0x65
+#define M98095_066_LVL_RCV             0x66
+#define M98095_067_LVL_SPK_L           0x67
+#define M98095_068_LVL_SPK_R           0x68
+#define M98095_069_MICAGC_CFG          0x69
+#define M98095_06A_MICAGC_THRESH       0x6A
+#define M98095_06B_SPK_NOISEGATE       0x6B
+#define M98095_06C_DAI1_ALC1_TIME      0x6C
+#define M98095_06D_DAI1_ALC1_COMP      0x6D
+#define M98095_06E_DAI1_ALC1_EXPN      0x6E
+#define M98095_06F_DAI1_ALC1_GAIN      0x6F
+#define M98095_070_DAI1_ALC2_TIME      0x70
+#define M98095_071_DAI1_ALC2_COMP      0x71
+#define M98095_072_DAI1_ALC2_EXPN      0x72
+#define M98095_073_DAI1_ALC2_GAIN      0x73
+#define M98095_074_DAI1_ALC3_TIME      0x74
+#define M98095_075_DAI1_ALC3_COMP      0x75
+#define M98095_076_DAI1_ALC3_EXPN      0x76
+#define M98095_077_DAI1_ALC3_GAIN      0x77
+#define M98095_078_DAI2_ALC1_TIME      0x78
+#define M98095_079_DAI2_ALC1_COMP      0x79
+#define M98095_07A_DAI2_ALC1_EXPN      0x7A
+#define M98095_07B_DAI2_ALC1_GAIN      0x7B
+#define M98095_07C_DAI2_ALC2_TIME      0x7C
+#define M98095_07D_DAI2_ALC2_COMP      0x7D
+#define M98095_07E_DAI2_ALC2_EXPN      0x7E
+#define M98095_07F_DAI2_ALC2_GAIN      0x7F
+#define M98095_080_DAI2_ALC3_TIME      0x80
+#define M98095_081_DAI2_ALC3_COMP      0x81
+#define M98095_082_DAI2_ALC3_EXPN      0x82
+#define M98095_083_DAI2_ALC3_GAIN      0x83
+#define M98095_084_HP_NOISE_GATE       0x84
+#define M98095_085_AUX_ADC             0x85
+#define M98095_086_CFG_LINE            0x86
+#define M98095_087_CFG_MIC             0x87
+#define M98095_088_CFG_LEVEL           0x88
+#define M98095_089_JACK_DET_AUTO       0x89
+#define M98095_08A_JACK_DET_MANUAL     0x8A
+#define M98095_08B_JACK_KEYSCAN_DBC    0x8B
+#define M98095_08C_JACK_KEYSCAN_DLY    0x8C
+#define M98095_08D_JACK_KEY_THRESH     0x8D
+#define M98095_08E_JACK_DC_SLEW                0x8E
+#define M98095_08F_JACK_TEST_CFG       0x8F
+#define M98095_090_PWR_EN_IN           0x90
+#define M98095_091_PWR_EN_OUT          0x91
+#define M98095_092_PWR_EN_OUT          0x92
+#define M98095_093_BIAS_CTRL           0x93
+#define M98095_094_PWR_DAC_21          0x94
+#define M98095_095_PWR_DAC_03          0x95
+#define M98095_096_PWR_DAC_CK          0x96
+#define M98095_097_PWR_SYS             0x97
+
+#define M98095_0FF_REV_ID              0xFF
+
+#define M98095_REG_CNT                 (0xFF+1)
+#define M98095_REG_MAX_CACHED          0X97
+
+/* MAX98095 Registers Bit Fields */
+
+/* M98095_00F_HOST_CFG */
+#define M98095_SEG                     (1<<0)
+#define M98095_XTEN                    (1<<1)
+#define M98095_MDLLEN                  (1<<2)
+
+/* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */
+#define M98095_CLKMODE_MASK            0xFF
+
+/* M98095_02A_DAI1_FORMAT, M98095_034_DAI2_FORMAT, M98095_03E_DAI3_FORMAT */
+#define M98095_DAI_MAS                 (1<<7)
+#define M98095_DAI_WCI                 (1<<6)
+#define M98095_DAI_BCI                 (1<<5)
+#define M98095_DAI_DLY                 (1<<4)
+#define M98095_DAI_TDM                 (1<<2)
+#define M98095_DAI_FSW                 (1<<1)
+#define M98095_DAI_WS                  (1<<0)
+
+/* M98095_02B_DAI1_CLOCK, M98095_035_DAI2_CLOCK, M98095_03F_DAI3_CLOCK */
+#define M98095_DAI_BSEL64              (1<<0)
+#define M98095_DAI_DOSR_DIV2           (0<<5)
+#define M98095_DAI_DOSR_DIV4           (1<<5)
+
+/* M98095_02C_DAI1_IOCFG, M98095_036_DAI2_IOCFG, M98095_040_DAI3_IOCFG */
+#define M98095_S1NORMAL                        (1<<6)
+#define M98095_S2NORMAL                        (2<<6)
+#define M98095_S3NORMAL                        (3<<6)
+#define M98095_SDATA                   (3<<0)
+
+/* M98095_02E_DAI1_FILTERS, M98095_038_DAI2_FILTERS, M98095_042_DAI3_FILTERS */
+#define M98095_DAI_DHF                 (1<<3)
+
+/* M98095_045_DSP_CFG */
+#define M98095_DSPNORMAL               (5<<4)
+
+/* M98095_048_MIX_DAC_LR */
+#define M98095_DAI1L_TO_DACR           (1<<7)
+#define M98095_DAI1R_TO_DACR           (1<<6)
+#define M98095_DAI2M_TO_DACR           (1<<5)
+#define M98095_DAI1L_TO_DACL           (1<<3)
+#define M98095_DAI1R_TO_DACL           (1<<2)
+#define M98095_DAI2M_TO_DACL           (1<<1)
+#define M98095_DAI3M_TO_DACL           (1<<0)
+
+/* M98095_049_MIX_DAC_M */
+#define M98095_DAI1L_TO_DACM           (1<<3)
+#define M98095_DAI1R_TO_DACM           (1<<2)
+#define M98095_DAI2M_TO_DACM           (1<<1)
+#define M98095_DAI3M_TO_DACM           (1<<0)
+
+/* M98095_04E_MIX_HP_CFG */
+#define M98095_HPNORMAL                        (3<<4)
+
+/* M98095_05F_LVL_MIC1, M98095_060_LVL_MIC2 */
+#define M98095_MICPRE_MASK             (3<<5)
+#define M98095_MICPRE_SHIFT            5
+
+/* M98095_064_LVL_HP_L, M98095_065_LVL_HP_R */
+#define M98095_HP_MUTE                 (1<<7)
+
+/* M98095_066_LVL_RCV */
+#define M98095_REC_MUTE                        (1<<7)
+
+/* M98095_067_LVL_SPK_L, M98095_068_LVL_SPK_R */
+#define M98095_SP_MUTE                 (1<<7)
+
+/* M98095_087_CFG_MIC */
+#define M98095_MICSEL_MASK             (3<<0)
+#define M98095_DIGMIC_L                        (1<<2)
+#define M98095_DIGMIC_R                        (1<<3)
+#define M98095_DIGMIC2L                        (1<<4)
+#define M98095_DIGMIC2R                        (1<<5)
+
+/* M98095_088_CFG_LEVEL */
+#define M98095_VSEN                    (1<<6)
+#define M98095_ZDEN                    (1<<5)
+#define M98095_BQ2EN                   (1<<3)
+#define M98095_BQ1EN                   (1<<2)
+#define M98095_EQ2EN                   (1<<1)
+#define M98095_EQ1EN                   (1<<0)
+
+/* M98095_090_PWR_EN_IN */
+#define M98095_INEN                    (1<<7)
+#define M98095_MB2EN                   (1<<3)
+#define M98095_MB1EN                   (1<<2)
+#define M98095_MBEN                    (3<<2)
+#define M98095_ADREN                   (1<<1)
+#define M98095_ADLEN                   (1<<0)
+
+/* M98095_091_PWR_EN_OUT */
+#define M98095_HPLEN                   (1<<7)
+#define M98095_HPREN                   (1<<6)
+#define M98095_SPLEN                   (1<<5)
+#define M98095_SPREN                   (1<<4)
+#define M98095_RECEN                   (1<<3)
+#define M98095_DALEN                   (1<<1)
+#define M98095_DAREN                   (1<<0)
+
+/* M98095_092_PWR_EN_OUT */
+#define M98095_SPK_FIXEDSPECTRUM       (0<<4)
+#define M98095_SPK_SPREADSPECTRUM      (1<<4)
+
+/* M98095_097_PWR_SYS */
+#define M98095_SHDNRUN                 (1<<7)
+#define M98095_PERFMODE                        (1<<3)
+#define M98095_HPPLYBACK               (1<<2)
+#define M98095_PWRSV8K                 (1<<1)
+#define M98095_PWRSV                   (1<<0)
+
+#define M98095_COEFS_PER_BAND          5
+
+/* Equalizer filter coefficients */
+#define M98095_110_DAI1_EQ_BASE                0x10
+#define M98095_142_DAI2_EQ_BASE                0x42
+
+/* Biquad filter coefficients */
+#define M98095_174_DAI1_BQ_BASE                0x74
+#define M98095_17E_DAI2_BQ_BASE                0x7E
+
+/* function prototype */
+
+/*
+ * intialise max98095 sound codec device for the given configuration
+ *
+ * @param blob                 FDT node for codec values
+ * @param sampling_rate                Sampling rate (Hz)
+ * @param mclk_freq            MCLK Frequency (Hz)
+ * @param bits_per_sample      bits per Sample (must be 16 or 24)
+ *
+ * @returns -1 for error and 0 Success.
+ */
+int max98095_init(const void *blob, int sampling_rate, int mclk_freq,
+                       int bits_per_sample);
+
+#endif
index fa8432d..a4bf4ad 100644 (file)
@@ -31,6 +31,7 @@
 #include <sound.h>
 #include <asm/arch/sound.h>
 #include "wm8994.h"
+#include "max98095.h"
 
 /* defines */
 #define SOUND_400_HZ 400
@@ -149,11 +150,15 @@ static int codec_init(const void *blob, struct i2stx_info *pi2s_tx)
                        pi2s_tx->samplingrate,
                        (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
                        pi2s_tx->bitspersample, pi2s_tx->channels);
+       } else if (!strcmp(codectype, "max98095")) {
+               ret = max98095_init(blob, pi2s_tx->samplingrate,
+                               (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
+                               pi2s_tx->bitspersample);
        } else {
-               debug("%s: Unknown code type %s\n", __func__,
-                     codectype);
+               debug("%s: Unknown codec type %s\n", __func__, codectype);
                return -1;
        }
+
        if (ret) {
                debug("%s: Codec init failed\n", __func__);
                return -1;
index 4268595..d08609e 100644 (file)
@@ -50,8 +50,10 @@ COBJS-$(CONFIG_OMAP3_SPI) += omap3_spi.o
 COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o
 COBJS-$(CONFIG_SH_SPI) += sh_spi.o
 COBJS-$(CONFIG_FSL_ESPI) += fsl_espi.o
-COBJS-$(CONFIG_TEGRA_SPI) += tegra_spi.o
-COBJS-$(CONFIG_TEGRA_SLINK) += tegra_slink.o
+COBJS-$(CONFIG_FDT_SPI) += fdt_spi.o
+COBJS-$(CONFIG_TEGRA20_SFLASH) += tegra20_sflash.o
+COBJS-$(CONFIG_TEGRA20_SLINK) += tegra20_slink.o
+COBJS-$(CONFIG_TEGRA114_SPI) += tegra114_spi.o
 COBJS-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 
 COBJS  := $(COBJS-y)
diff --git a/drivers/spi/fdt_spi.c b/drivers/spi/fdt_spi.c
new file mode 100644 (file)
index 0000000..58f139a
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Common fdt based SPI driver front end
+ *
+ * Copyright (c) 2013 NVIDIA Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 <malloc.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/clock.h>
+#include <asm/arch-tegra/clk_rst.h>
+#include <asm/arch-tegra20/tegra20_sflash.h>
+#include <asm/arch-tegra20/tegra20_slink.h>
+#include <asm/arch-tegra114/tegra114_spi.h>
+#include <spi.h>
+#include <fdtdec.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct fdt_spi_driver {
+       int compat;
+       int max_ctrls;
+       int (*init)(int *node_list, int count);
+       int (*claim_bus)(struct spi_slave *slave);
+       int (*release_bus)(struct spi_slave *slave);
+       int (*cs_is_valid)(unsigned int bus, unsigned int cs);
+       struct spi_slave *(*setup_slave)(unsigned int bus, unsigned int cs,
+                                       unsigned int max_hz, unsigned int mode);
+       void (*free_slave)(struct spi_slave *slave);
+       void (*cs_activate)(struct spi_slave *slave);
+       void (*cs_deactivate)(struct spi_slave *slave);
+       int (*xfer)(struct spi_slave *slave, unsigned int bitlen,
+                   const void *data_out, void *data_in, unsigned long flags);
+};
+
+static struct fdt_spi_driver fdt_spi_drivers[] = {
+#ifdef CONFIG_TEGRA20_SFLASH
+       {
+               .compat         = COMPAT_NVIDIA_TEGRA20_SFLASH,
+               .max_ctrls      = 1,
+               .init           = tegra20_spi_init,
+               .claim_bus      = tegra20_spi_claim_bus,
+               .cs_is_valid    = tegra20_spi_cs_is_valid,
+               .setup_slave    = tegra20_spi_setup_slave,
+               .free_slave     = tegra20_spi_free_slave,
+               .cs_activate    = tegra20_spi_cs_activate,
+               .cs_deactivate  = tegra20_spi_cs_deactivate,
+               .xfer           = tegra20_spi_xfer,
+       },
+#endif
+#ifdef CONFIG_TEGRA20_SLINK
+       {
+               .compat         = COMPAT_NVIDIA_TEGRA20_SLINK,
+               .max_ctrls      = CONFIG_TEGRA_SLINK_CTRLS,
+               .init           = tegra30_spi_init,
+               .claim_bus      = tegra30_spi_claim_bus,
+               .cs_is_valid    = tegra30_spi_cs_is_valid,
+               .setup_slave    = tegra30_spi_setup_slave,
+               .free_slave     = tegra30_spi_free_slave,
+               .cs_activate    = tegra30_spi_cs_activate,
+               .cs_deactivate  = tegra30_spi_cs_deactivate,
+               .xfer           = tegra30_spi_xfer,
+       },
+#endif
+#ifdef CONFIG_TEGRA114_SPI
+       {
+               .compat         = COMPAT_NVIDIA_TEGRA114_SPI,
+               .max_ctrls      = CONFIG_TEGRA114_SPI_CTRLS,
+               .init           = tegra114_spi_init,
+               .claim_bus      = tegra114_spi_claim_bus,
+               .cs_is_valid    = tegra114_spi_cs_is_valid,
+               .setup_slave    = tegra114_spi_setup_slave,
+               .free_slave     = tegra114_spi_free_slave,
+               .cs_activate    = tegra114_spi_cs_activate,
+               .cs_deactivate  = tegra114_spi_cs_deactivate,
+               .xfer           = tegra114_spi_xfer,
+       },
+#endif
+};
+
+static struct fdt_spi_driver *driver;
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+       if (!driver)
+               return 0;
+       else if (!driver->cs_is_valid)
+               return 1;
+       else
+               return driver->cs_is_valid(bus, cs);
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+               unsigned int max_hz, unsigned int mode)
+{
+       if (!driver || !driver->setup_slave)
+               return NULL;
+
+       return driver->setup_slave(bus, cs, max_hz, mode);
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+       if (driver && driver->free_slave)
+               return driver->free_slave(slave);
+}
+
+static int spi_init_driver(struct fdt_spi_driver *driver)
+{
+       int count;
+       int node_list[driver->max_ctrls];
+
+       count = fdtdec_find_aliases_for_id(gd->fdt_blob, "spi",
+                                          driver->compat,
+                                          node_list,
+                                          driver->max_ctrls);
+       return driver->init(node_list, count);
+}
+
+void spi_init(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(fdt_spi_drivers); i++) {
+               driver = &fdt_spi_drivers[i];
+               if (!spi_init_driver(driver))
+                       break;
+       }
+       if (i == ARRAY_SIZE(fdt_spi_drivers))
+               driver = NULL;
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+       if (!driver)
+               return 1;
+       if (!driver->claim_bus)
+               return 0;
+
+       return driver->claim_bus(slave);
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+       if (driver && driver->release_bus)
+               driver->release_bus(slave);
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+       if (driver && driver->cs_activate)
+               driver->cs_activate(slave);
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+       if (driver && driver->cs_deactivate)
+               driver->cs_deactivate(slave);
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+            const void *data_out, void *data_in, unsigned long flags)
+{
+       if (!driver || !driver->xfer)
+               return -1;
+
+       return driver->xfer(slave, bitlen, data_out, data_in, flags);
+}
diff --git a/drivers/spi/tegra114_spi.c b/drivers/spi/tegra114_spi.c
new file mode 100644 (file)
index 0000000..b11a0a1
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+ * NVIDIA Tegra SPI controller (T114 and later)
+ *
+ * Copyright (c) 2010-2013 NVIDIA Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 <malloc.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/clock.h>
+#include <asm/arch-tegra/clk_rst.h>
+#include <asm/arch-tegra114/tegra114_spi.h>
+#include <spi.h>
+#include <fdtdec.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* COMMAND1 */
+#define SPI_CMD1_GO                    (1 << 31)
+#define SPI_CMD1_M_S                   (1 << 30)
+#define SPI_CMD1_MODE_MASK             0x3
+#define SPI_CMD1_MODE_SHIFT            28
+#define SPI_CMD1_CS_SEL_MASK           0x3
+#define SPI_CMD1_CS_SEL_SHIFT          26
+#define SPI_CMD1_CS_POL_INACTIVE3      (1 << 25)
+#define SPI_CMD1_CS_POL_INACTIVE2      (1 << 24)
+#define SPI_CMD1_CS_POL_INACTIVE1      (1 << 23)
+#define SPI_CMD1_CS_POL_INACTIVE0      (1 << 22)
+#define SPI_CMD1_CS_SW_HW              (1 << 21)
+#define SPI_CMD1_CS_SW_VAL             (1 << 20)
+#define SPI_CMD1_IDLE_SDA_MASK         0x3
+#define SPI_CMD1_IDLE_SDA_SHIFT                18
+#define SPI_CMD1_BIDIR                 (1 << 17)
+#define SPI_CMD1_LSBI_FE               (1 << 16)
+#define SPI_CMD1_LSBY_FE               (1 << 15)
+#define SPI_CMD1_BOTH_EN_BIT           (1 << 14)
+#define SPI_CMD1_BOTH_EN_BYTE          (1 << 13)
+#define SPI_CMD1_RX_EN                 (1 << 12)
+#define SPI_CMD1_TX_EN                 (1 << 11)
+#define SPI_CMD1_PACKED                        (1 << 5)
+#define SPI_CMD1_BIT_LEN_MASK          0x1F
+#define SPI_CMD1_BIT_LEN_SHIFT         0
+
+/* COMMAND2 */
+#define SPI_CMD2_TX_CLK_TAP_DELAY      (1 << 6)
+#define SPI_CMD2_TX_CLK_TAP_DELAY_MASK (0x3F << 6)
+#define SPI_CMD2_RX_CLK_TAP_DELAY      (1 << 0)
+#define SPI_CMD2_RX_CLK_TAP_DELAY_MASK (0x3F << 0)
+
+/* TRANSFER STATUS */
+#define SPI_XFER_STS_RDY               (1 << 30)
+
+/* FIFO STATUS */
+#define SPI_FIFO_STS_CS_INACTIVE       (1 << 31)
+#define SPI_FIFO_STS_FRAME_END         (1 << 30)
+#define SPI_FIFO_STS_RX_FIFO_FLUSH     (1 << 15)
+#define SPI_FIFO_STS_TX_FIFO_FLUSH     (1 << 14)
+#define SPI_FIFO_STS_ERR               (1 << 8)
+#define SPI_FIFO_STS_TX_FIFO_OVF       (1 << 7)
+#define SPI_FIFO_STS_TX_FIFO_UNR       (1 << 6)
+#define SPI_FIFO_STS_RX_FIFO_OVF       (1 << 5)
+#define SPI_FIFO_STS_RX_FIFO_UNR       (1 << 4)
+#define SPI_FIFO_STS_TX_FIFO_FULL      (1 << 3)
+#define SPI_FIFO_STS_TX_FIFO_EMPTY     (1 << 2)
+#define SPI_FIFO_STS_RX_FIFO_FULL      (1 << 1)
+#define SPI_FIFO_STS_RX_FIFO_EMPTY     (1 << 0)
+
+#define SPI_TIMEOUT            1000
+#define TEGRA_SPI_MAX_FREQ     52000000
+
+struct spi_regs {
+       u32 command1;   /* 000:SPI_COMMAND1 register */
+       u32 command2;   /* 004:SPI_COMMAND2 register */
+       u32 timing1;    /* 008:SPI_CS_TIM1 register */
+       u32 timing2;    /* 00c:SPI_CS_TIM2 register */
+       u32 xfer_status;/* 010:SPI_TRANS_STATUS register */
+       u32 fifo_status;/* 014:SPI_FIFO_STATUS register */
+       u32 tx_data;    /* 018:SPI_TX_DATA register */
+       u32 rx_data;    /* 01c:SPI_RX_DATA register */
+       u32 dma_ctl;    /* 020:SPI_DMA_CTL register */
+       u32 dma_blk;    /* 024:SPI_DMA_BLK register */
+       u32 rsvd[56];   /* 028-107 reserved */
+       u32 tx_fifo;    /* 108:SPI_FIFO1 register */
+       u32 rsvd2[31];  /* 10c-187 reserved */
+       u32 rx_fifo;    /* 188:SPI_FIFO2 register */
+       u32 spare_ctl;  /* 18c:SPI_SPARE_CTRL register */
+};
+
+struct tegra_spi_ctrl {
+       struct spi_regs *regs;
+       unsigned int freq;
+       unsigned int mode;
+       int periph_id;
+       int valid;
+};
+
+struct tegra_spi_slave {
+       struct spi_slave slave;
+       struct tegra_spi_ctrl *ctrl;
+};
+
+static struct tegra_spi_ctrl spi_ctrls[CONFIG_TEGRA114_SPI_CTRLS];
+
+static inline struct tegra_spi_slave *to_tegra_spi(struct spi_slave *slave)
+{
+       return container_of(slave, struct tegra_spi_slave, slave);
+}
+
+int tegra114_spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+       if (bus >= CONFIG_TEGRA114_SPI_CTRLS || cs > 3 || !spi_ctrls[bus].valid)
+               return 0;
+       else
+               return 1;
+}
+
+struct spi_slave *tegra114_spi_setup_slave(unsigned int bus, unsigned int cs,
+               unsigned int max_hz, unsigned int mode)
+{
+       struct tegra_spi_slave *spi;
+
+       debug("%s: bus: %u, cs: %u, max_hz: %u, mode: %u\n", __func__,
+               bus, cs, max_hz, mode);
+
+       if (!spi_cs_is_valid(bus, cs)) {
+               printf("SPI error: unsupported bus %d / chip select %d\n",
+                      bus, cs);
+               return NULL;
+       }
+
+       if (max_hz > TEGRA_SPI_MAX_FREQ) {
+               printf("SPI error: unsupported frequency %d Hz. Max frequency"
+                       " is %d Hz\n", max_hz, TEGRA_SPI_MAX_FREQ);
+               return NULL;
+       }
+
+       spi = malloc(sizeof(struct tegra_spi_slave));
+       if (!spi) {
+               printf("SPI error: malloc of SPI structure failed\n");
+               return NULL;
+       }
+       spi->slave.bus = bus;
+       spi->slave.cs = cs;
+       spi->ctrl = &spi_ctrls[bus];
+       if (!spi->ctrl) {
+               printf("SPI error: could not find controller for bus %d\n",
+                      bus);
+               return NULL;
+       }
+
+       if (max_hz < spi->ctrl->freq) {
+               debug("%s: limiting frequency from %u to %u\n", __func__,
+                     spi->ctrl->freq, max_hz);
+               spi->ctrl->freq = max_hz;
+       }
+       spi->ctrl->mode = mode;
+
+       return &spi->slave;
+}
+
+void tegra114_spi_free_slave(struct spi_slave *slave)
+{
+       struct tegra_spi_slave *spi = to_tegra_spi(slave);
+
+       free(spi);
+}
+
+int tegra114_spi_init(int *node_list, int count)
+{
+       struct tegra_spi_ctrl *ctrl;
+       int i;
+       int node = 0;
+       int found = 0;
+
+       for (i = 0; i < count; i++) {
+               ctrl = &spi_ctrls[i];
+               node = node_list[i];
+
+               ctrl->regs = (struct spi_regs *)fdtdec_get_addr(gd->fdt_blob,
+                                                                node, "reg");
+               if ((fdt_addr_t)ctrl->regs == FDT_ADDR_T_NONE) {
+                       debug("%s: no spi register found\n", __func__);
+                       continue;
+               }
+               ctrl->freq = fdtdec_get_int(gd->fdt_blob, node,
+                                           "spi-max-frequency", 0);
+               if (!ctrl->freq) {
+                       debug("%s: no spi max frequency found\n", __func__);
+                       continue;
+               }
+
+               ctrl->periph_id = clock_decode_periph_id(gd->fdt_blob, node);
+               if (ctrl->periph_id == PERIPH_ID_NONE) {
+                       debug("%s: could not decode periph id\n", __func__);
+                       continue;
+               }
+               ctrl->valid = 1;
+               found = 1;
+
+               debug("%s: found controller at %p, freq = %u, periph_id = %d\n",
+                     __func__, ctrl->regs, ctrl->freq, ctrl->periph_id);
+       }
+
+       return !found;
+}
+
+int tegra114_spi_claim_bus(struct spi_slave *slave)
+{
+       struct tegra_spi_slave *spi = to_tegra_spi(slave);
+       struct spi_regs *regs = spi->ctrl->regs;
+
+       /* Change SPI clock to correct frequency, PLLP_OUT0 source */
+       clock_start_periph_pll(spi->ctrl->periph_id, CLOCK_ID_PERIPH,
+                              spi->ctrl->freq);
+
+       /* Clear stale status here */
+       setbits_le32(&regs->fifo_status,
+                    SPI_FIFO_STS_ERR           |
+                    SPI_FIFO_STS_TX_FIFO_OVF   |
+                    SPI_FIFO_STS_TX_FIFO_UNR   |
+                    SPI_FIFO_STS_RX_FIFO_OVF   |
+                    SPI_FIFO_STS_RX_FIFO_UNR   |
+                    SPI_FIFO_STS_TX_FIFO_FULL  |
+                    SPI_FIFO_STS_TX_FIFO_EMPTY |
+                    SPI_FIFO_STS_RX_FIFO_FULL  |
+                    SPI_FIFO_STS_RX_FIFO_EMPTY);
+       debug("%s: FIFO STATUS = %08x\n", __func__, readl(&regs->fifo_status));
+
+       /* Set master mode and sw controlled CS */
+       setbits_le32(&regs->command1, SPI_CMD1_M_S | SPI_CMD1_CS_SW_HW |
+                    (spi->ctrl->mode << SPI_CMD1_MODE_SHIFT));
+       debug("%s: COMMAND1 = %08x\n", __func__, readl(&regs->command1));
+
+       return 0;
+}
+
+void tegra114_spi_cs_activate(struct spi_slave *slave)
+{
+       struct tegra_spi_slave *spi = to_tegra_spi(slave);
+       struct spi_regs *regs = spi->ctrl->regs;
+
+       clrbits_le32(&regs->command1, SPI_CMD1_CS_SW_VAL);
+}
+
+void tegra114_spi_cs_deactivate(struct spi_slave *slave)
+{
+       struct tegra_spi_slave *spi = to_tegra_spi(slave);
+       struct spi_regs *regs = spi->ctrl->regs;
+
+       setbits_le32(&regs->command1, SPI_CMD1_CS_SW_VAL);
+}
+
+int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+               const void *data_out, void *data_in, unsigned long flags)
+{
+       struct tegra_spi_slave *spi = to_tegra_spi(slave);
+       struct spi_regs *regs = spi->ctrl->regs;
+       u32 reg, tmpdout, tmpdin = 0;
+       const u8 *dout = data_out;
+       u8 *din = data_in;
+       int num_bytes;
+       int ret;
+
+       debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
+             __func__, slave->bus, slave->cs, dout, din, bitlen);
+       if (bitlen % 8)
+               return -1;
+       num_bytes = bitlen / 8;
+
+       ret = 0;
+
+       /* clear all error status bits */
+       reg = readl(&regs->fifo_status);
+       writel(reg, &regs->fifo_status);
+
+       /* clear ready bit */
+       setbits_le32(&regs->xfer_status, SPI_XFER_STS_RDY);
+
+       clrsetbits_le32(&regs->command1, SPI_CMD1_CS_SW_VAL,
+                       SPI_CMD1_RX_EN | SPI_CMD1_TX_EN | SPI_CMD1_LSBY_FE |
+                       (slave->cs << SPI_CMD1_CS_SEL_SHIFT));
+
+       /* set xfer size to 1 block (32 bits) */
+       writel(0, &regs->dma_blk);
+
+       if (flags & SPI_XFER_BEGIN)
+               spi_cs_activate(slave);
+
+       /* handle data in 32-bit chunks */
+       while (num_bytes > 0) {
+               int bytes;
+               int is_read = 0;
+               int tm, i;
+
+               tmpdout = 0;
+               bytes = (num_bytes > 4) ?  4 : num_bytes;
+
+               if (dout != NULL) {
+                       for (i = 0; i < bytes; ++i)
+                               tmpdout = (tmpdout << 8) | dout[i];
+                       dout += bytes;
+               }
+
+               num_bytes -= bytes;
+
+               clrsetbits_le32(&regs->command1,
+                               SPI_CMD1_BIT_LEN_MASK << SPI_CMD1_BIT_LEN_SHIFT,
+                               (bytes * 8 - 1) << SPI_CMD1_BIT_LEN_SHIFT);
+               writel(tmpdout, &regs->tx_fifo);
+               setbits_le32(&regs->command1, SPI_CMD1_GO);
+
+               /*
+                * Wait for SPI transmit FIFO to empty, or to time out.
+                * The RX FIFO status will be read and cleared last
+                */
+               for (tm = 0, is_read = 0; tm < SPI_TIMEOUT; ++tm) {
+                       u32 fifo_status, xfer_status;
+
+                       fifo_status = readl(&regs->fifo_status);
+
+                       /* We can exit when we've had both RX and TX activity */
+                       if (is_read &&
+                           (fifo_status & SPI_FIFO_STS_TX_FIFO_EMPTY))
+                               break;
+
+                       xfer_status = readl(&regs->xfer_status);
+                       if (!(xfer_status & SPI_XFER_STS_RDY))
+                               continue;
+
+                       if (fifo_status & SPI_FIFO_STS_ERR) {
+                               debug("%s: got a fifo error: ", __func__);
+                               if (fifo_status & SPI_FIFO_STS_TX_FIFO_OVF)
+                                       debug("tx FIFO overflow ");
+                               if (fifo_status & SPI_FIFO_STS_TX_FIFO_UNR)
+                                       debug("tx FIFO underrun ");
+                               if (fifo_status & SPI_FIFO_STS_RX_FIFO_OVF)
+                                       debug("rx FIFO overflow ");
+                               if (fifo_status & SPI_FIFO_STS_RX_FIFO_UNR)
+                                       debug("rx FIFO underrun ");
+                               if (fifo_status & SPI_FIFO_STS_TX_FIFO_FULL)
+                                       debug("tx FIFO full ");
+                               if (fifo_status & SPI_FIFO_STS_TX_FIFO_EMPTY)
+                                       debug("tx FIFO empty ");
+                               if (fifo_status & SPI_FIFO_STS_RX_FIFO_FULL)
+                                       debug("rx FIFO full ");
+                               if (fifo_status & SPI_FIFO_STS_RX_FIFO_EMPTY)
+                                       debug("rx FIFO empty ");
+                               debug("\n");
+                               break;
+                       }
+
+                       if (!(fifo_status & SPI_FIFO_STS_RX_FIFO_EMPTY)) {
+                               tmpdin = readl(&regs->rx_fifo);
+                               is_read = 1;
+
+                               /* swap bytes read in */
+                               if (din != NULL) {
+                                       for (i = bytes - 1; i >= 0; --i) {
+                                               din[i] = tmpdin & 0xff;
+                                               tmpdin >>= 8;
+                                       }
+                                       din += bytes;
+                               }
+                       }
+               }
+
+               if (tm >= SPI_TIMEOUT)
+                       ret = tm;
+
+               /* clear ACK RDY, etc. bits */
+               writel(readl(&regs->fifo_status), &regs->fifo_status);
+       }
+
+       if (flags & SPI_XFER_END)
+               spi_cs_deactivate(slave);
+
+       debug("%s: transfer ended. Value=%08x, fifo_status = %08x\n",
+             __func__, tmpdin, readl(&regs->fifo_status));
+
+       if (ret) {
+               printf("%s: timeout during SPI transfer, tm %d\n",
+                      __func__, ret);
+               return -1;
+       }
+
+       return 0;
+}