* [RFC/PATCH] ARM: add Tegra support
@ 2010-03-09 16:38 Mike Rapoport
2010-03-14 6:51 ` Mike Rapoport
` (3 more replies)
0 siblings, 4 replies; 37+ messages in thread
From: Mike Rapoport @ 2010-03-09 16:38 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds basic support for Nvidia Tegra2 platform.
From 13fac106b9383478a3337e443a946286998536d7 Mon Sep 17 00:00:00 2001
From: Mike Rapoport <mike@compulab.co.il>
Date: Tue, 9 Mar 2010 18:35:45 +0200
Subject: [PATCH] ARM: add Tegra support
Signed-off-by: Mike Rapoport <mike@compulab.co.il>
---
arch/arm/Kconfig | 13 +
arch/arm/Makefile | 1 +
arch/arm/mach-tegra/Kconfig | 27 +
arch/arm/mach-tegra/Makefile | 12 +
arch/arm/mach-tegra/Makefile.boot | 1 +
arch/arm/mach-tegra/board-harmony.c | 93 +++
arch/arm/mach-tegra/clock.c | 105 +++
arch/arm/mach-tegra/clock.h | 84 +++
arch/arm/mach-tegra/common.h | 26 +
arch/arm/mach-tegra/gpio.c | 335 ++++++++++
arch/arm/mach-tegra/include/mach/clkdev.h | 29 +
arch/arm/mach-tegra/include/mach/debug-macro.S | 29 +
arch/arm/mach-tegra/include/mach/entry-macro.S | 113 ++++
arch/arm/mach-tegra/include/mach/gpio.h | 44 ++
arch/arm/mach-tegra/include/mach/hardware.h | 58 ++
arch/arm/mach-tegra/include/mach/io.h | 35 +
arch/arm/mach-tegra/include/mach/irqs.h | 169 +++++
arch/arm/mach-tegra/include/mach/memory.h | 24 +
arch/arm/mach-tegra/include/mach/system.h | 34 +
arch/arm/mach-tegra/include/mach/tegra.h | 110 ++++
arch/arm/mach-tegra/include/mach/timex.h | 22 +
arch/arm/mach-tegra/include/mach/uncompress.h | 46 ++
arch/arm/mach-tegra/include/mach/vmalloc.h | 22 +
arch/arm/mach-tegra/io.c | 73 +++
arch/arm/mach-tegra/irq.c | 31 +
arch/arm/mach-tegra/tegra2_clocks.c | 809 ++++++++++++++++++++++++
arch/arm/mach-tegra/timer.c | 182 ++++++
27 files changed, 2527 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-tegra/Kconfig
create mode 100644 arch/arm/mach-tegra/Makefile
create mode 100644 arch/arm/mach-tegra/Makefile.boot
create mode 100644 arch/arm/mach-tegra/board-harmony.c
create mode 100644 arch/arm/mach-tegra/clock.c
create mode 100644 arch/arm/mach-tegra/clock.h
create mode 100644 arch/arm/mach-tegra/common.h
create mode 100644 arch/arm/mach-tegra/gpio.c
create mode 100644 arch/arm/mach-tegra/include/mach/clkdev.h
create mode 100644 arch/arm/mach-tegra/include/mach/debug-macro.S
create mode 100644 arch/arm/mach-tegra/include/mach/entry-macro.S
create mode 100644 arch/arm/mach-tegra/include/mach/gpio.h
create mode 100644 arch/arm/mach-tegra/include/mach/hardware.h
create mode 100644 arch/arm/mach-tegra/include/mach/io.h
create mode 100644 arch/arm/mach-tegra/include/mach/irqs.h
create mode 100644 arch/arm/mach-tegra/include/mach/memory.h
create mode 100644 arch/arm/mach-tegra/include/mach/system.h
create mode 100644 arch/arm/mach-tegra/include/mach/tegra.h
create mode 100644 arch/arm/mach-tegra/include/mach/timex.h
create mode 100644 arch/arm/mach-tegra/include/mach/uncompress.h
create mode 100644 arch/arm/mach-tegra/include/mach/vmalloc.h
create mode 100644 arch/arm/mach-tegra/io.c
create mode 100644 arch/arm/mach-tegra/irq.c
create mode 100644 arch/arm/mach-tegra/tegra2_clocks.c
create mode 100644 arch/arm/mach-tegra/timer.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3b18128..d479cd8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -750,6 +750,17 @@ config ARCH_U8500
help
Support for ST-Ericsson's Ux500 architecture
+config ARCH_TEGRA
+ bool "NVIDIA Tegra"
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ select GENERIC_GPIO
+ select HAVE_CLK
+ select COMMON_CLKDEV
+ help
+ This enables support for NVIDIA Tegra based systems (Tegra APX,
+ Tegra 6xx and Tegra 2 series).
+
endchoice
source "arch/arm/mach-aaec2000/Kconfig"
@@ -852,6 +863,8 @@ if ARCH_S5PC1XX
source "arch/arm/mach-s5pc100/Kconfig"
endif
+source "arch/arm/mach-tegra/Kconfig"
+
source "arch/arm/mach-u300/Kconfig"
source "arch/arm/mach-ux500/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 81f54ca..9f2a5fe 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -167,6 +167,7 @@ machine-$(CONFIG_ARCH_SA1100) := sa1100
machine-$(CONFIG_ARCH_SHARK) := shark
machine-$(CONFIG_ARCH_STMP378X) := stmp378x
machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx
+machine-$(CONFIG_ARCH_TEGRA) := tegra
machine-$(CONFIG_ARCH_U300) := u300
machine-$(CONFIG_ARCH_U8500) := ux500
machine-$(CONFIG_ARCH_VERSATILE) := versatile
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
new file mode 100644
index 0000000..731405f
--- /dev/null
+++ b/arch/arm/mach-tegra/Kconfig
@@ -0,0 +1,27 @@
+if ARCH_TEGRA
+
+comment "NVIDIA Tegra options"
+
+choice
+ prompt "Tegra processor family"
+
+config ARCH_TEGRA_2x_SOC
+ bool "Tegra 2 family"
+ select CPU_V7
+ select ARM_GIC
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ Support for NVIDIA Tegra AP20 and T20 processors, based on the
+ ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
+
+endchoice
+
+
+comment "Tegra-based boards"
+
+config MACH_HARMONY
+ bool "Harmony board"
+ help
+ Support for nVidia Harmony development platform
+
+endif
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
new file mode 100644
index 0000000..ed4fb3b
--- /dev/null
+++ b/arch/arm/mach-tegra/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y += irq.o io.o
+
+# SoC-specific support
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o tegra2_clocks.o timer.o gpio.o
+
+# Board-specific support
+obj-$(CONFIG_MACH_HARMONY) += board-harmony.o
diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot
new file mode 100644
index 0000000..dae9661
--- /dev/null
+++ b/arch/arm/mach-tegra/Makefile.boot
@@ -0,0 +1 @@
+zreladdr-y := 0x00008000
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
new file mode 100644
index 0000000..f713393
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -0,0 +1,93 @@
+/*
+ * arch/arm/mach-tegra/board-harmony.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/setup.h>
+
+#include <mach/hardware.h>
+
+#include "common.h"
+
+static struct plat_serial8250_port debug_uart_platform_data[] = {
+ {
+ .membase = IO_ADDRESS(TEGRA_UARTD_BASE),
+ .mapbase = TEGRA_UARTD_BASE,
+ .irq = INT_UARTD,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 216000000/16 * 16,
+ }, {
+ .flags = 0
+ }
+};
+
+static struct platform_device debug_uart = {
+ .name = "serial8250",
+ .id = 0,
+ .dev = {
+ .platform_data = debug_uart_platform_data,
+ },
+};
+
+static struct platform_device *harmony_devices[] __initdata = {
+ &debug_uart,
+};
+
+static void __init tegra_harmony_fixup(struct machine_desc *desc,
+ struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ mi->nr_banks = 2;
+ mi->bank[0].start = PHYS_OFFSET;
+ mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
+ mi->bank[0].size = (448*1024*1024);
+ mi->bank[1].start = 512*1024*1024;
+ mi->bank[1].node = PHYS_TO_NID(512*1024*1024);
+ mi->bank[1].size = (512*1024*1024);
+}
+
+static void __init tegra_harmony_init(void)
+{
+ struct clk *clk;
+
+ clk = clk_get_sys(NULL, "pll_p");
+ clk_enable(clk);
+ clk_set_rate(clk, 216000000);
+
+ clk = clk_get_sys("uart.3", NULL);
+ clk_set_rate(clk, 216000000);
+ clk_enable(clk);
+
+ platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices));
+}
+
+MACHINE_START(HARMONY, "harmony")
+ .boot_params = 0x00000100,
+ .phys_io = IO_APB_PHYS,
+ .io_pg_offst = ((IO_APB_VIRT) >> 18) & 0xfffc,
+ .timer = &tegra_timer,
+ .init_irq = tegra_init_irq,
+ .map_io = tegra_map_common_io,
+ .init_machine = tegra_harmony_init,
+ .fixup = tegra_harmony_fixup,
+MACHINE_END
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
new file mode 100644
index 0000000..729ddb5
--- /dev/null
+++ b/arch/arm/mach-tegra/clock.c
@@ -0,0 +1,105 @@
+/*
+ * arch/arm/mach-tegra/clock.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <asm/clkdev.h>
+
+#include "clock.h"
+
+static DEFINE_SPINLOCK(clk_spinlock);
+
+int clk_enable(struct clk *c)
+{
+ int ret = 0;
+ unsigned long flags;
+ if (c->refcnt == 0) {
+ if (c->parent) {
+ ret = clk_enable(c->parent);
+ if (ret)
+ goto err;
+ }
+
+ if (c->ops && c->ops->enable) {
+ spin_lock_irqsave(&clk_spinlock, flags);
+ ret = c->ops->enable(c);
+ spin_unlock_irqrestore(&clk_spinlock, flags);
+ if (ret) {
+ if (c->parent)
+ clk_disable(c->parent);
+ goto err;
+ }
+ }
+ }
+ c->refcnt++;
+err:
+ return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *c)
+{
+ unsigned long flags;
+ if (c->refcnt == 0) {
+ WARN(1, "Trying to disable clock %s with refcnt 0", c->name);
+ return;
+ }
+
+ if (c->refcnt == 1) {
+ if (c->parent)
+ clk_disable(c->parent);
+
+ if (c->ops && c->ops->disable) {
+ spin_lock_irqsave(&clk_spinlock, flags);
+ c->ops->disable(c);
+ spin_unlock_irqrestore(&clk_spinlock, flags);
+ }
+ }
+ c->refcnt--;
+}
+EXPORT_SYMBOL(clk_disable);
+
+int clk_set_parent(struct clk *c, struct clk *parent)
+{
+ if (c->ops && c->ops->set_parent)
+ return c->ops->set_parent(c, parent);
+ else
+ BUG();
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+int clk_set_rate(struct clk *c, unsigned long rate)
+{
+ if (c->ops && c->ops->set_rate)
+ return c->ops->set_rate(c, rate);
+ else
+ BUG();
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+unsigned long clk_get_rate(struct clk *c)
+{
+ if (c->ops && c->ops->get_rate)
+ return c->ops->get_rate(c);
+ else if (c->parent)
+ return clk_get_rate(c->parent);
+ else
+ BUG();
+}
+EXPORT_SYMBOL(clk_get_rate);
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
new file mode 100644
index 0000000..a6c77bb
--- /dev/null
+++ b/arch/arm/mach-tegra/clock.h
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/mach-tegra/include/mach/clock.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#define ENABLE_ON_INIT 0x00000001
+#define DIV_U71 0x00000002
+#define DIV_U71_FIXED 0x00000004
+#define DIV_2 0x00000008
+#define PLL_FIXED 0x00000010
+#define PLL_HAS_CPCON 0x00000020
+#define MUX 0x00000040
+
+struct clk;
+
+struct clk_mux_sel {
+ struct clk *input;
+ u32 value;
+};
+
+struct clk_pll_table {
+ unsigned long input_rate;
+ unsigned long output_rate;
+ u16 n;
+ u16 m;
+ u8 p;
+ u8 cpcon;
+};
+
+struct clk_ops {
+ void (*init)(struct clk *);
+ int (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+ void (*recalc)(struct clk *);
+ int (*set_parent)(struct clk *, struct clk *);
+ int (*set_rate)(struct clk *, unsigned long);
+ unsigned long (*get_rate)(struct clk *);
+ long (*round_rate)(struct clk *, unsigned long);
+};
+
+struct clk {
+ const char *name;
+ struct clk_ops *ops;
+ struct clk *parent;
+ unsigned long rate;
+ u32 flags;
+ u32 refcnt;
+ u32 reg;
+ u32 reg_shift;
+ unsigned int clk_num;
+
+ /* PLL */
+ unsigned long input_min;
+ unsigned long input_max;
+ unsigned long cf_min;
+ unsigned long cf_max;
+ unsigned long vco_min;
+ unsigned long vco_max;
+ u32 m;
+ u32 n;
+ u32 p;
+ u32 cpcon;
+ const struct clk_pll_table *pll_table;
+
+ /* DIV */
+
+ /* MUX */
+ const struct clk_mux_sel *inputs;
+ u32 sel;
+ u32 reg_mask;
+};
+
+extern void tegra2_arch_clk_init(void);
diff --git a/arch/arm/mach-tegra/common.h b/arch/arm/mach-tegra/common.h
new file mode 100644
index 0000000..4430e36
--- /dev/null
+++ b/arch/arm/mach-tegra/common.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-tegra/include/mach/board.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_TEGRA_BOARD_H
+#define __MACH_TEGRA_BOARD_H
+
+extern struct sys_timer tegra_timer;
+
+void __init tegra_map_common_io(void);
+void __init tegra_init_irq(void);
+void __init tegra_init_clock(void);
+
+#endif
diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c
new file mode 100644
index 0000000..9625bd2
--- /dev/null
+++ b/arch/arm/mach-tegra/gpio.c
@@ -0,0 +1,335 @@
+/*
+ * arch/arm/mach-tegra/gpio.c
+ *
+ * Copyright (c) 2010 Google, Inc
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/gpio.h>
+
+#include <mach/hardware.h>
+
+#define GPIO_BANK(x) ((x) >> 5)
+#define GPIO_PORT(x) (((x) >> 3) & 0x3)
+#define GPIO_BIT(x) ((x) & 0x7)
+
+#define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \
+ GPIO_BANK(x) * 0x80 + \
+ GPIO_PORT(x) * 4)
+
+#define GPIO_CNF(x) (GPIO_REG(x) + 0x00)
+#define GPIO_OE(x) (GPIO_REG(x) + 0x10)
+#define GPIO_OUT(x) (GPIO_REG(x) + 0X20)
+#define GPIO_IN(x) (GPIO_REG(x) + 0x30)
+#define GPIO_INT_STA(x) (GPIO_REG(x) + 0x40)
+#define GPIO_INT_ENB(x) (GPIO_REG(x) + 0x50)
+#define GPIO_INT_LVL(x) (GPIO_REG(x) + 0x60)
+#define GPIO_INT_CLR(x) (GPIO_REG(x) + 0x70)
+
+#define GPIO_MSK_CNF(x) (GPIO_REG(x) + 0x800)
+#define GPIO_MSK_OE(x) (GPIO_REG(x) + 0x810)
+#define GPIO_MSK_OUT(x) (GPIO_REG(x) + 0X820)
+#define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + 0x840)
+#define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + 0x850)
+#define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + 0x860)
+
+#define GPIO_INT_LVL_MASK 0x010101
+#define GPIO_INT_LVL_EDGE_RISING 0x000101
+#define GPIO_INT_LVL_EDGE_FALLING 0x000100
+#define GPIO_INT_LVL_EDGE_BOTH 0x010100
+#define GPIO_INT_LVL_LEVEL_HIGH 0x000001
+#define GPIO_INT_LVL_LEVEL_LOW 0x000000
+
+struct tegra_gpio_bank {
+ int bank;
+ int irq;
+ spinlock_t lvl_lock[4];
+};
+
+static struct tegra_gpio_bank tegra_gpio_banks[] = {
+ {.bank = 0, .irq = INT_GPIO1},
+ {.bank = 1, .irq = INT_GPIO2},
+ {.bank = 2, .irq = INT_GPIO3},
+ {.bank = 3, .irq = INT_GPIO4},
+ {.bank = 4, .irq = INT_GPIO5},
+ {.bank = 5, .irq = INT_GPIO6},
+ {.bank = 6, .irq = INT_GPIO7},
+};
+
+static int tegra_gpio_compose(int bank, int port, int bit)
+{
+ return (bank << 5) | ((port & 0x3) << 3) | (bit & 0x7);
+}
+
+static void tegra_gpio_mask_write(u32 reg, int gpio, int value)
+{
+ u32 val;
+
+ val = 0x100 << GPIO_BIT(gpio);
+ if (value)
+ val |= 1 << GPIO_BIT(gpio);
+ __raw_writel(val, reg);
+}
+
+static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ tegra_gpio_mask_write(GPIO_MSK_OUT(offset), offset, value);
+}
+
+static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ return (__raw_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1;
+}
+
+static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 0);
+ return 0;
+}
+
+static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 1);
+ return 0;
+}
+
+static struct gpio_chip tegra_gpio_chip = {
+ .label = "tegra-gpio",
+ .direction_input = tegra_gpio_direction_input,
+ .get = tegra_gpio_get,
+ .direction_output = tegra_gpio_direction_output,
+ .set = tegra_gpio_set,
+ .base = 0,
+ .ngpio = ARCH_NR_GPIOS,
+};
+
+static void tegra_gpio_irq_ack(unsigned int irq)
+{
+ int gpio = irq - INT_GPIO_BASE;
+
+ __raw_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio));
+}
+
+static void tegra_gpio_irq_mask(unsigned int irq)
+{
+ int gpio = irq - INT_GPIO_BASE;
+
+ tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0);
+}
+
+static void tegra_gpio_irq_unmask(unsigned int irq)
+{
+ int gpio = irq - INT_GPIO_BASE;
+
+ tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1);
+}
+
+static int tegra_gpio_irq_set_type(unsigned int irq, unsigned int type)
+{
+ int gpio = irq - INT_GPIO_BASE;
+ struct tegra_gpio_bank *bank = get_irq_data(irq);
+ int port = GPIO_PORT(gpio);
+ int lvl_type;
+ int val;
+ unsigned long flags;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ lvl_type = GPIO_INT_LVL_EDGE_RISING;
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ lvl_type = GPIO_INT_LVL_EDGE_FALLING;
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ lvl_type = GPIO_INT_LVL_EDGE_BOTH;
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ lvl_type = GPIO_INT_LVL_LEVEL_HIGH;
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ lvl_type = GPIO_INT_LVL_LEVEL_LOW;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&bank->lvl_lock[port], flags);
+
+ val = __raw_readl(GPIO_INT_LVL(gpio));
+ val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio));
+ val |= lvl_type << GPIO_BIT(gpio);
+ __raw_writel(val, GPIO_INT_LVL(gpio));
+
+ spin_unlock_irqrestore(&bank->lvl_lock[port], flags);
+
+ if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
+ __set_irq_handler_unlocked(irq, handle_level_irq);
+ else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+ __set_irq_handler_unlocked(irq, handle_edge_irq);
+
+ return 0;
+}
+
+static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ struct tegra_gpio_bank *bank;
+ int port;
+ int pin;
+ int unmasked = 0;
+
+ desc->chip->ack(irq);
+
+ bank = get_irq_data(irq);
+
+ for (port = 0; port < 4; port++) {
+ int gpio = tegra_gpio_compose(bank->bank, port, 0);
+ unsigned long sta = __raw_readl(GPIO_INT_STA(gpio)) &
+ __raw_readl(GPIO_INT_ENB(gpio));
+ u32 lvl = __raw_readl(GPIO_INT_LVL(gpio));
+
+ for_each_bit(pin, &sta, 8) {
+ __raw_writel(1 << pin, GPIO_INT_CLR(gpio));
+
+ /* if gpio is edge triggered, clear condition
+ * before executing the hander so that we don't
+ * miss edges
+ */
+ if (lvl & (0x100 << pin)) {
+ unmasked = 1;
+ desc->chip->unmask(irq);
+ }
+
+ generic_handle_irq(gpio_to_irq(gpio + pin));
+ }
+ }
+
+ if (!unmasked)
+ desc->chip->unmask(irq);
+
+}
+
+
+static struct irq_chip tegra_gpio_irq_chip = {
+ .name = "GPIO",
+ .ack = tegra_gpio_irq_ack,
+ .mask = tegra_gpio_irq_mask,
+ .unmask = tegra_gpio_irq_unmask,
+ .set_type = tegra_gpio_irq_set_type,
+};
+
+
+/* This lock class tells lockdep that GPIO irqs are in a different
+ * category than their parents, so it won't report false recursion.
+ */
+static struct lock_class_key gpio_lock_class;
+
+static int __init tegra_gpio_init(void)
+{
+ struct tegra_gpio_bank *bank;
+ int i;
+ int j;
+
+ for (i = 0; i < 7; i++) {
+ for (j = 0; j < 4; j++) {
+ int gpio = tegra_gpio_compose(i, j, 0);
+ __raw_writel(0x00, GPIO_INT_ENB(gpio));
+ }
+ }
+
+ gpiochip_add(&tegra_gpio_chip);
+
+ for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + ARCH_NR_GPIOS); i++) {
+ bank = &tegra_gpio_banks[GPIO_BANK(i)];
+
+ lockdep_set_class(&irq_desc[i].lock, &gpio_lock_class);
+ set_irq_chip_data(i, bank);
+ set_irq_chip(i, &tegra_gpio_irq_chip);
+ set_irq_handler(i, handle_simple_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
+ bank = &tegra_gpio_banks[i];
+
+ set_irq_chained_handler(bank->irq, tegra_gpio_irq_handler);
+ set_irq_data(bank->irq, bank);
+
+ for (j = 0; j < 4; j++)
+ spin_lock_init(&bank->lvl_lock[j]);
+ }
+
+ return 0;
+}
+
+postcore_initcall(tegra_gpio_init);
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static int dbg_gpio_show(struct seq_file *s, void *unused)
+{
+ int i;
+ int j;
+
+ for (i = 0; i < 7; i++) {
+ for (j = 0; j < 4; j++) {
+ int gpio = tegra_gpio_compose(i, j, 0);
+ seq_printf(s, "%d:%d %02x %02x %02x %02x %02x %02x %06x\n",
+ i, j,
+ __raw_readl(GPIO_CNF(gpio)),
+ __raw_readl(GPIO_OE(gpio)),
+ __raw_readl(GPIO_OUT(gpio)),
+ __raw_readl(GPIO_IN(gpio)),
+ __raw_readl(GPIO_INT_STA(gpio)),
+ __raw_readl(GPIO_INT_ENB(gpio)),
+ __raw_readl(GPIO_INT_LVL(gpio)));
+ }
+ }
+ return 0;
+}
+
+static int dbg_gpio_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dbg_gpio_show, &inode->i_private);
+}
+
+static const struct file_operations debug_fops = {
+ .open = dbg_gpio_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init tegra_gpio_debuginit(void)
+{
+ (void) debugfs_create_file("tegra_gpio", S_IRUGO,
+ NULL, NULL, &debug_fops);
+ return 0;
+}
+late_initcall(tegra_gpio_debuginit);
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/clkdev.h b/arch/arm/mach-tegra/include/mach/clkdev.h
new file mode 100644
index 0000000..f3dd0d3
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/clkdev.h
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-tegra/include/mach/clkdev.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+static inline int __clk_get(struct clk *clk)
+{
+ return 1;
+}
+
+static inline void __clk_put(struct clk *clk)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S
new file mode 100644
index 0000000..0c119f3
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/debug-macro.S
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-tegra/include/mach/debug-macro.S
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#include <mach/hardware.h>
+
+ .macro addruart, rx, tmp
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+ ldreq \rx, =IO_APB_PHYS @ physical
+ ldrne \rx, =IO_APB_VIRT @ virtual
+ orr \rx, \rx, #0x6300 @ UART D
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
+
diff --git a/arch/arm/mach-tegra/include/mach/entry-macro.S b/arch/arm/mach-tegra/include/mach/entry-macro.S
new file mode 100644
index 0000000..05a618c
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/entry-macro.S
@@ -0,0 +1,113 @@
+/*
+ * arch/arm/mach-tegra/include/mach/entry-macro.S
+ *
+ * Copyright (C) 2009 Palm, Inc.
+ *
+ * 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.
+ *
+ */
+#include <mach/hardware.h>
+
+#if defined(CONFIG_ARM_GIC)
+
+#include <asm/hardware/gic.h>
+
+ /* Uses the GIC interrupt controller built into the cpu */
+#define ICTRL_BASE (IO_CPU_VIRT + 0x100)
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ movw \base, #(ICTRL_BASE & 0x0000ffff)
+ movt \base, #((ICTRL_BASE & 0xffff0000) >> 16)
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ /*
+ * The interrupt numbering scheme is defined in the
+ * interrupt controller spec. To wit:
+ *
+ * Interrupts 0-15 are IPI
+ * 16-28 are reserved
+ * 29-31 are local. We allow 30 to be used for the watchdog.
+ * 32-1020 are global
+ * 1021-1022 are reserved
+ * 1023 is "spurious" (no interrupt)
+ *
+ * For now, we ignore all local interrupts so only return an
+ * interrupt if it's between 30 and 1020. The test_for_ipi
+ * routine below will pick up on IPIs.
+ *
+ * A simple read from the controller will tell us the number
+ * of the highest priority enabled interrupt. We then just
+ * need to check whether it is in the valid range for an IRQ
+ * (30-1020 inclusive).
+ */
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ /* bits 12-10 = src CPU, 9-0 = int # */
+ ldr \irqstat, [\base, #GIC_CPU_INTACK]
+ ldr \tmp, =1021
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #29
+ cmpcc \irqnr, \irqnr
+ cmpne \irqnr, \tmp
+ cmpcs \irqnr, \irqnr
+ .endm
+
+ /*
+ * We assume that irqstat (the raw value of the IRQ acknowledge
+ * register) is preserved from the macro above.
+ * If there is an IPI, we immediately signal end of interrupt on the
+ * controller, since this requires the original irqstat value which
+ * we won't easily be able to recreate later.
+ */
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #16
+ strcc \irqstat, [\base, #GIC_CPU_EOI]
+ cmpcs \irqnr, \irqnr
+ .endm
+
+ /* As above, this assumes that irqstat and base are preserved.. */
+ .macro test_for_ltirq, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ mov \tmp, #0
+ cmp \irqnr, #29
+ moveq \tmp, #1
+ streq \irqstat, [\base, #GIC_CPU_EOI]
+ cmp \tmp, #0
+ .endm
+
+#else
+ /* legacy interrupt controller for AP16 */
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ @ enable imprecise aborts
+ cpsie a
+ @ EVP base at 0xf010f000
+ mov \base, #0xf0000000
+ orr \base, #0x00100000
+ orr \base, #0x0000f000
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqnr, [\base, #0x20] @ EVT_IRQ_STS
+ cmp \irqnr, #0x80
+ .endm
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/gpio.h b/arch/arm/mach-tegra/include/mach/gpio.h
new file mode 100644
index 0000000..612f49e
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/gpio.h
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/mach-tegra/include/mach/gpio.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_TEGRA_GPIO_H
+#define __MACH_TEGRA_GPIO_H
+
+#include <mach/irqs.h>
+
+#define ARCH_NR_GPIOS INT_GPIO_NR
+
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
+static inline int gpio_to_irq(unsigned int gpio)
+{
+ if (gpio < ARCH_NR_GPIOS)
+ return INT_GPIO_BASE + gpio;
+ return -EINVAL;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+ if ((irq >= INT_GPIO_BASE) && (irq < INT_GPIO_BASE + INT_GPIO_NR))
+ return irq - INT_GPIO_BASE;
+ return -EINVAL;
+}
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/hardware.h b/arch/arm/mach-tegra/include/mach/hardware.h
new file mode 100644
index 0000000..381adb1
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/hardware.h
@@ -0,0 +1,58 @@
+/*
+ * arch/arm/mach-tegra/include/mach/hardware.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_TEGRA_HARDWARE_H
+#define __MACH_TEGRA_HARDWARE_H
+
+#include "tegra.h"
+
+/* On TEGRA, many peripherals are very closely packed in
+ * two 256MB io windows (that actually only use about 64KB
+ *@the start of each).
+ *
+ * We will just map the first 1MB of each window (to minimize
+ * pt entries needed) and provide a macro to transform physical
+ * io addresses to an appropriate void __iomem *.
+ *
+ */
+
+#define IO_CPU_PHYS 0x50040000
+#define IO_CPU_VIRT 0xFE000000
+#define IO_CPU_SIZE SZ_16K
+
+#define IO_PPSB_PHYS 0x60000000
+#define IO_PPSB_VIRT 0xFE200000
+#define IO_PPSB_SIZE SZ_1M
+
+#define IO_APB_PHYS 0x70000000
+#define IO_APB_VIRT 0xFE300000
+#define IO_APB_SIZE SZ_1M
+
+#define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz)))
+#define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst)))
+
+#define IO_TO_VIRT(n) ( \
+ IO_TO_VIRT_BETWEEN((n), IO_PPSB_PHYS, IO_PPSB_SIZE) ? \
+ IO_TO_VIRT_XLATE((n), IO_PPSB_PHYS, IO_PPSB_VIRT) : \
+ IO_TO_VIRT_BETWEEN((n), IO_APB_PHYS, IO_APB_SIZE) ? \
+ IO_TO_VIRT_XLATE((n), IO_APB_PHYS, IO_APB_VIRT) : \
+ IO_TO_VIRT_BETWEEN((n), IO_CPU_PHYS, IO_CPU_SIZE) ? \
+ IO_TO_VIRT_XLATE((n), IO_CPU_PHYS, IO_CPU_VIRT) : \
+ 0)
+
+#define IO_ADDRESS(n) ((void __iomem *) IO_TO_VIRT(n))
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h
new file mode 100644
index 0000000..7198934
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/io.h
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/mach-tegra/include/mach/io.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_TEGRA_IO_H
+#define __MACH_TEGRA_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#ifndef __ASSEMBLER__
+
+#define __arch_ioremap(p, s, t) tegra_ioremap(p, s, t)
+#define __arch_iounmap(v) tegra_iounmap(v)
+
+void __iomem *tegra_ioremap(unsigned long phys, size_t size, unsigned int type);
+void tegra_iounmap(volatile void __iomem *addr);
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
new file mode 100644
index 0000000..230fae3
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -0,0 +1,169 @@
+/*
+ * arch/arm/mach-tegra/include/mach/irqs.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_TEGRA_IRQS_H
+#define __MACH_TEGRA_IRQS_H
+
+#define INT_GIC_BASE 0
+
+#define IRQ_LOCALTIMER 29
+
+/* Primary Interrupt Controller */
+#define INT_PRI_BASE (INT_GIC_BASE + 32)
+#define INT_TMR1 (INT_PRI_BASE + 0)
+#define INT_TMR2 (INT_PRI_BASE + 1)
+#define INT_RTC (INT_PRI_BASE + 2)
+#define INT_I2S2 (INT_PRI_BASE + 3)
+#define INT_SHR_SEM_INBOX_IBF (INT_PRI_BASE + 4)
+#define INT_SHR_SEM_INBOX_IBE (INT_PRI_BASE + 5)
+#define INT_SHR_SEM_OUTBOX_IBF (INT_PRI_BASE + 6)
+#define INT_SHR_SEM_OUTBOX_IBE (INT_PRI_BASE + 7)
+#define INT_VDE_UCQ_ERROR (INT_PRI_BASE + 8)
+#define INT_VDE_SYNC_TOKEN (INT_PRI_BASE + 9)
+#define INT_VDE_BSE_V (INT_PRI_BASE + 10)
+#define INT_VDE_BSE_A (INT_PRI_BASE + 11)
+#define INT_VDE_SXE (INT_PRI_BASE + 12)
+#define INT_I2S1 (INT_PRI_BASE + 13)
+#define INT_SDMMC1 (INT_PRI_BASE + 14)
+#define INT_SDMMC2 (INT_PRI_BASE + 15)
+#define INT_XIO (INT_PRI_BASE + 16)
+#define INT_VDE (INT_PRI_BASE + 17)
+#define INT_AVP_UCQ (INT_PRI_BASE + 18)
+#define INT_SDMMC3 (INT_PRI_BASE + 19)
+#define INT_USB (INT_PRI_BASE + 20)
+#define INT_USB2 (INT_PRI_BASE + 21)
+#define INT_PRI_RES_22 (INT_PRI_BASE + 22)
+#define INT_EIDE (INT_PRI_BASE + 23)
+#define INT_NANDFLASH (INT_PRI_BASE + 24)
+#define INT_VCP (INT_PRI_BASE + 25)
+#define INT_APB_DMA (INT_PRI_BASE + 26)
+#define INT_AHB_DMA (INT_PRI_BASE + 27)
+#define INT_GNT_0 (INT_PRI_BASE + 28)
+#define INT_GNT_1 (INT_PRI_BASE + 29)
+#define INT_OWR (INT_PRI_BASE + 30)
+#define INT_SDMMC4 (INT_PRI_BASE + 31)
+
+/* Secondary Interrupt Controller */
+#define INT_SEC_BASE (INT_PRI_BASE + 32)
+#define INT_GPIO1 (INT_SEC_BASE + 0)
+#define INT_GPIO2 (INT_SEC_BASE + 1)
+#define INT_GPIO3 (INT_SEC_BASE + 2)
+#define INT_GPIO4 (INT_SEC_BASE + 3)
+#define INT_UARTA (INT_SEC_BASE + 4)
+#define INT_UARTB (INT_SEC_BASE + 5)
+#define INT_I2C (INT_SEC_BASE + 6)
+#define INT_SPI (INT_SEC_BASE + 7)
+#define INT_TWC (INT_SEC_BASE + 8)
+#define INT_TMR3 (INT_SEC_BASE + 9)
+#define INT_TMR4 (INT_SEC_BASE + 10)
+#define INT_FLOW_RSM0 (INT_SEC_BASE + 11)
+#define INT_FLOW_RSM1 (INT_SEC_BASE + 12)
+#define INT_SPDIF (INT_SEC_BASE + 13)
+#define INT_UARTC (INT_SEC_BASE + 14)
+#define INT_MIPI (INT_SEC_BASE + 15)
+#define INT_EVENTA (INT_SEC_BASE + 16)
+#define INT_EVENTB (INT_SEC_BASE + 17)
+#define INT_EVENTC (INT_SEC_BASE + 18)
+#define INT_EVENTD (INT_SEC_BASE + 19)
+#define INT_VFIR (INT_SEC_BASE + 20)
+#define INT_DVC (INT_SEC_BASE + 21)
+#define INT_SYS_STATS_MON (INT_SEC_BASE + 22)
+#define INT_GPIO5 (INT_SEC_BASE + 23)
+#define INT_CPU0_PMU_INTR (INT_SEC_BASE + 24)
+#define INT_CPU2_PMU_INTR (INT_SEC_BASE + 25)
+#define INT_SEC_RES_26 (INT_SEC_BASE + 26)
+#define INT_S_LINK1 (INT_SEC_BASE + 27)
+#define INT_APB_DMA_COP (INT_SEC_BASE + 28)
+#define INT_AHB_DMA_COP (INT_SEC_BASE + 29)
+#define INT_DMA_TX (INT_SEC_BASE + 30)
+#define INT_DMA_RX (INT_SEC_BASE + 31)
+
+/* Tertiary Interrupt Controller */
+#define INT_TRI_BASE (INT_SEC_BASE + 32)
+#define INT_HOST1X_COP_SYNCPT (INT_TRI_BASE + 0)
+#define INT_HOST1X_MPCORE_SYNCPT (INT_TRI_BASE + 1)
+#define INT_HOST1X_COP_GENERAL (INT_TRI_BASE + 2)
+#define INT_HOST1X_MPCORE_GENERAL (INT_TRI_BASE + 3)
+#define INT_MPE_GENERAL (INT_TRI_BASE + 4)
+#define INT_VI_GENERAL (INT_TRI_BASE + 5)
+#define INT_EPP_GENERAL (INT_TRI_BASE + 6)
+#define INT_ISP_GENERAL (INT_TRI_BASE + 7)
+#define INT_2D_GENERAL (INT_TRI_BASE + 8)
+#define INT_DISPLAY_GENERAL (INT_TRI_BASE + 9)
+#define INT_DISPLAY_B_GENERAL (INT_TRI_BASE + 10)
+#define INT_HDMI (INT_TRI_BASE + 11)
+#define INT_TVO_GENERAL (INT_TRI_BASE + 12)
+#define INT_MC_GENERAL (INT_TRI_BASE + 13)
+#define INT_EMC_GENERAL (INT_TRI_BASE + 14)
+#define INT_TRI_RES_15 (INT_TRI_BASE + 15)
+#define INT_TRI_RES_16 (INT_TRI_BASE + 16)
+#define INT_AC97 (INT_TRI_BASE + 17)
+#define INT_SPI_2 (INT_TRI_BASE + 18)
+#define INT_SPI_3 (INT_TRI_BASE + 19)
+#define INT_I2C2 (INT_TRI_BASE + 20)
+#define INT_KBC (INT_TRI_BASE + 21)
+#define INT_EXTERNAL_PMU (INT_TRI_BASE + 22)
+#define INT_GPIO6 (INT_TRI_BASE + 23)
+#define INT_TVDAC (INT_TRI_BASE + 24)
+#define INT_GPIO7 (INT_TRI_BASE + 25)
+#define INT_UARTD (INT_TRI_BASE + 26)
+#define INT_UARTE (INT_TRI_BASE + 27)
+#define INT_I2C3 (INT_TRI_BASE + 28)
+#define INT_SPI4 (INT_TRI_BASE + 29)
+#define INT_TRI_RES_30 (INT_TRI_BASE + 30)
+#define INT_SW_RESERVED (INT_TRI_BASE + 31)
+
+/* Quaternary Interrupt Controller */
+#define INT_QUAD_BASE (INT_TRI_BASE + 32)
+#define INT_SNOR (INT_QUAD_BASE + 0)
+#define INT_USB3 (INT_QUAD_BASE + 1)
+#define INT_PCIE_INTR (INT_QUAD_BASE + 2)
+#define INT_PCIE_MSI (INT_QUAD_BASE + 3)
+#define INT_QUAD_RES_4 (INT_QUAD_BASE + 4)
+#define INT_QUAD_RES_5 (INT_QUAD_BASE + 5)
+#define INT_QUAD_RES_6 (INT_QUAD_BASE + 6)
+#define INT_QUAD_RES_7 (INT_QUAD_BASE + 7)
+#define INT_APB_DMA_CH0 (INT_QUAD_BASE + 8)
+#define INT_APB_DMA_CH1 (INT_QUAD_BASE + 9)
+#define INT_APB_DMA_CH2 (INT_QUAD_BASE + 10)
+#define INT_APB_DMA_CH3 (INT_QUAD_BASE + 11)
+#define INT_APB_DMA_CH4 (INT_QUAD_BASE + 12)
+#define INT_APB_DMA_CH5 (INT_QUAD_BASE + 13)
+#define INT_APB_DMA_CH6 (INT_QUAD_BASE + 14)
+#define INT_APB_DMA_CH7 (INT_QUAD_BASE + 15)
+#define INT_APB_DMA_CH8 (INT_QUAD_BASE + 16)
+#define INT_APB_DMA_CH9 (INT_QUAD_BASE + 17)
+#define INT_APB_DMA_CH10 (INT_QUAD_BASE + 18)
+#define INT_APB_DMA_CH11 (INT_QUAD_BASE + 19)
+#define INT_APB_DMA_CH12 (INT_QUAD_BASE + 20)
+#define INT_APB_DMA_CH13 (INT_QUAD_BASE + 21)
+#define INT_APB_DMA_CH14 (INT_QUAD_BASE + 22)
+#define INT_APB_DMA_CH15 (INT_QUAD_BASE + 23)
+#define INT_QUAD_RES_24 (INT_QUAD_BASE + 24)
+#define INT_QUAD_RES_25 (INT_QUAD_BASE + 25)
+#define INT_QUAD_RES_26 (INT_QUAD_BASE + 26)
+#define INT_QUAD_RES_27 (INT_QUAD_BASE + 27)
+#define INT_QUAD_RES_28 (INT_QUAD_BASE + 28)
+#define INT_QUAD_RES_29 (INT_QUAD_BASE + 29)
+#define INT_QUAD_RES_30 (INT_QUAD_BASE + 30)
+#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31)
+
+#define INT_GPIO_BASE (INT_QUAD_BASE + 32)
+#define INT_GPIO_NR (28 * 8)
+
+#define NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR)
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/memory.h b/arch/arm/mach-tegra/include/mach/memory.h
new file mode 100644
index 0000000..9507b08
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/memory.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-tegra/include/mach/memory.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_TEGRA_MEMORY_H
+#define __MACH_TEGRA_MEMORY_H
+
+/* physical offset of RAM */
+#define PHYS_OFFSET UL(0)
+
+#endif
+
diff --git a/arch/arm/mach-tegra/include/mach/system.h b/arch/arm/mach-tegra/include/mach/system.h
new file mode 100644
index 0000000..0aef65a
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/system.h
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/mach-tegra/include/mach/system.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_TEGRA_SYSTEM_H
+#define __MACH_TEGRA_SYSTEM_H
+
+#include <mach/hardware.h>
+
+static inline void arch_idle(void)
+{
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ void __iomem *reset = IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x04);
+ u32 reg = readl(reset);
+ reg |= 0x04;
+ writel(reg, reset);
+}
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/tegra.h b/arch/arm/mach-tegra/include/mach/tegra.h
new file mode 100644
index 0000000..9ef99ee
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra.h
@@ -0,0 +1,110 @@
+/*
+ * arch/arm/mach-tegra/include/mach/iomap.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_TEGRA_IOMAP_H
+#define __MACH_TEGRA_IOMAP_H
+
+#include <asm/sizes.h>
+
+#define TEGRA_ARM_PERIF_BASE 0x50040000
+#define TEGRA_ARM_PERIF_SIZE SZ_8K
+
+#define TEGRA_ARM_INT_DIST_BASE 0x50041000
+#define TEGRA_ARM_INT_DIST_SIZE SZ_4K
+
+#define TEGRA_DISPLAY_BASE 0x54200000
+#define TEGRA_DISPLAY_SIZE SZ_256K
+
+#define TEGRA_DISPLAY2_BASE 0x54240000
+#define TEGRA_DISPLAY2_SIZE SZ_256K
+
+#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000
+#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64
+
+#define TEGRA_SECONDARY_ICTLR_BASE 0x60004100
+#define TEGRA_SECONDARY_ICTLR_SIZE SZ_64
+
+#define TEGRA_TERTIARY_ICTLR_BASE 0x60004200
+#define TEGRA_TERTIARY_ICTLR_SIZE SZ_64
+
+#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300
+#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64
+
+#define TEGRA_TMR1_BASE 0x60005000
+#define TEGRA_TMR1_SIZE SZ_8
+
+#define TEGRA_TMR2_BASE 0x60005008
+#define TEGRA_TMR2_SIZE SZ_8
+
+#define TEGRA_TMRUS_BASE 0x60005010
+#define TEGRA_TMRUS_SIZE SZ_64
+
+#define TEGRA_TMR3_BASE 0x60005050
+#define TEGRA_TMR3_SIZE SZ_8
+
+#define TEGRA_TMR4_BASE 0x60005058
+#define TEGRA_TMR4_SIZE SZ_8
+
+#define TEGRA_CLK_RESET_BASE 0x60006000
+#define TEGRA_CLK_RESET_SIZE SZ_4K
+
+#define TEGRA_FLOW_CTRL_BASE 0x60007000
+#define TEGRA_FLOW_CTRL_SIZE 20
+
+#define TEGRA_GPIO_BASE 0x6000D000
+#define TEGRA_GPIO_SIZE SZ_1K
+
+#define TEGRA_EXCEPTION_VECTORS_BASE 0x6000F000
+#define TEGRA_EXCEPTION_VECTORS_SIZE SZ_4K
+
+#define TEGRA_APB_MISC_BASE 0x70000000
+#define TEGRA_APB_MISC_SIZE SZ_4K
+
+#define TEGRA_UARTA_BASE 0x70006000
+#define TEGRA_UARTA_SIZE SZ_64
+
+#define TEGRA_UARTB_BASE 0x70006040
+#define TEGRA_UARTB_SIZE SZ_64
+
+#define TEGRA_UARTC_BASE 0x70006200
+#define TEGRA_UARTC_SIZE SZ_256
+
+#define TEGRA_UARTD_BASE 0x70006300
+#define TEGRA_UARTD_SIZE SZ_256
+
+#define TEGRA_UARTE_BASE 0x70006400
+#define TEGRA_UARTE_SIZE SZ_256
+
+#define TEGRA_NAND_BASE 0x70008000
+#define TEGRA_NAND_SIZE SZ_256
+
+#define TEGRA_RTC_BASE 0x7000E000
+#define TEGRA_RTC_SIZE SZ_256
+
+#define TEGRA_PMC_BASE 0x7000E400
+#define TEGRA_PMC_SIZE SZ_256
+
+#define TEGRA_USB_BASE 0xC5000000
+#define TEGRA_USB_SIZE SZ_16K
+
+#define TEGRA_USB1_BASE 0xC5004000
+#define TEGRA_USB1_SIZE SZ_16K
+
+#define TEGRA_USB2_BASE 0xC5008000
+#define TEGRA_USB2_SIZE SZ_16K
+
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/timex.h b/arch/arm/mach-tegra/include/mach/timex.h
new file mode 100644
index 0000000..8e1a3c4
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/timex.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-tegra/include/mach/timex.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_TEGRA_TIMEX_H
+#define __MACH_TEGRA_TIMEX_H
+
+#define CLOCK_TICK_RATE 1000000
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h
new file mode 100644
index 0000000..1400798
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/uncompress.h
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-tegra/include/mach/uncompress.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_TEGRA_UNCOMPRESS_H
+#define __MACH_TEGRA_UNCOMPRESS_H
+
+#include <linux/serial_reg.h>
+
+#include "tegra.h"
+
+static void putc(int c)
+{
+ volatile u8 *uart = (volatile u8 *)(TEGRA_UARTD_BASE);
+ int shift = 2;
+
+ while (!(uart[UART_LSR << shift] & UART_LSR_THRE))
+ barrier();
+ uart[UART_TX << shift] = c;
+}
+
+static inline void flush(void)
+{
+}
+
+static inline void arch_decomp_setup(void)
+{
+}
+
+static inline void arch_decomp_wdog(void)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/vmalloc.h b/arch/arm/mach-tegra/include/mach/vmalloc.h
new file mode 100644
index 0000000..33444b1
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-tegra/include/mach/vmalloc.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_TEGRA_VMALLOC_H
+#define __MACH_TEGRA_VMALLOC_H
+
+#define VMALLOC_END ((PAGE_OFFSET) + 0x38000000)
+
+#endif
diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c
new file mode 100644
index 0000000..f856269
--- /dev/null
+++ b/arch/arm/mach-tegra/io.c
@@ -0,0 +1,73 @@
+/*
+ * arch/arm/mach-tegra/io.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+
+static struct map_desc tegra_io_desc[] __initdata = {
+ {
+ .virtual = IO_PPSB_VIRT,
+ .pfn = __phys_to_pfn(IO_PPSB_PHYS),
+ .length = IO_PPSB_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = IO_APB_VIRT,
+ .pfn = __phys_to_pfn(IO_APB_PHYS),
+ .length = IO_APB_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = IO_CPU_VIRT,
+ .pfn = __phys_to_pfn(IO_CPU_PHYS),
+ .length = IO_CPU_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init tegra_map_common_io(void)
+{
+ iotable_init(tegra_io_desc, ARRAY_SIZE(tegra_io_desc));
+}
+
+/*
+ * Intercept ioremap() requests for addresses in our fixed mapping regions.
+ */
+void __iomem *tegra_ioremap(unsigned long p, size_t size, unsigned int type)
+{
+ void __iomem *v = IO_ADDRESS(p);
+ if (v == NULL)
+ v = __arm_ioremap(p, size, type);
+ return v;
+}
+EXPORT_SYMBOL(tegra_ioremap);
+
+void tegra_iounmap(volatile void __iomem *addr)
+{
+ unsigned long virt = (unsigned long)addr;
+
+ if (virt >= VMALLOC_START && virt < VMALLOC_END)
+ __iounmap(addr);
+}
+EXPORT_SYMBOL(tegra_iounmap);
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
new file mode 100644
index 0000000..9690a1b
--- /dev/null
+++ b/arch/arm/mach-tegra/irq.c
@@ -0,0 +1,31 @@
+/*
+ * arch/arm/mach-tegra/irq.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+
+#include <asm/hardware/gic.h>
+
+#include <mach/hardware.h>
+
+#include "common.h"
+
+void __init tegra_init_irq(void)
+{
+ gic_dist_init(0, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), 29);
+ gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
+ tegra_init_clock();
+}
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
new file mode 100644
index 0000000..e480625
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -0,0 +1,809 @@
+/*
+ * arch/arm/mach-tegra/tegra2_clocks.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+
+#include <mach/hardware.h>
+
+#include "clock.h"
+
+#define CLK_RST_CONTROLLER_RST_DEVICES 0x004
+#define CLK_RST_CONTROLLER_RST_DEVICES_SET_CLR 0x300
+#define CLK_RST_CONTROLLER_CLK_OUT_ENB 0x010
+#define CLK_RST_CONTROLLER_CLK_OUT_ENB_SET_CLR 0x320
+#define CLK_RST_CONTROLLER_CLK_SOURCE 0x100
+
+static void __iomem *reg_clk_base;
+
+#define clk_writel(value, reg) \
+ __raw_writel(value, (u32)reg_clk_base + (reg))
+#define clk_readl(reg) \
+ __raw_readl((u32)reg_clk_base + (reg))
+
+static int clk_div71_possible_rate(struct clk *c, unsigned long rate)
+{
+ unsigned long input_rate = clk_get_rate(c);
+ int divider_u71;
+
+ divider_u71 = (input_rate*2)/rate;
+ if (rate * divider_u71 == input_rate*2)
+ return divider_u71 - 2;
+ else
+ return -1;
+}
+
+/* Default clk ops */
+static int tegra2_clk_enable(struct clk *c)
+{
+ return 0;
+}
+
+static void tegra2_clk_disable(struct clk *c)
+{
+}
+
+static unsigned long tegra2_clk_get_rate(struct clk *c)
+{
+ return c->rate;
+}
+
+/* clk_m functions */
+static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c)
+{
+ u32 clk_autodetect;
+ u32 auto_clk_ctl = clk_readl(0x50) & ~(3<<30);
+
+ clk_writel(0x80000001, 0x58);
+
+ while ((clk_autodetect = clk_readl(0x5c)) & 0x80000000)
+ ;
+
+ switch (clk_autodetect) {
+ case 732:
+ case 733:
+ c->rate = 12000000;
+ auto_clk_ctl |= 2<<30;
+ break;
+ case 794:
+ c->rate = 13000000;
+ auto_clk_ctl |= 0<<30;
+ break;
+ case 1172:
+ c->rate = 19200000;
+ auto_clk_ctl |= 1<<30;
+ break;
+ case 1587:
+ c->rate = 26000000;
+ auto_clk_ctl |= 3<<30;
+ break;
+ default:
+ WARN(1, "Unexpected clock autodetect value %d", clk_autodetect);
+ }
+
+ clk_writel(auto_clk_ctl, 0x50);
+
+ return c->rate;
+}
+
+static void tegra2_clk_m_init(struct clk *c)
+{
+ tegra2_clk_m_autodetect_rate(c);
+}
+
+static int tegra2_clk_m_enable(struct clk *c)
+{
+ return 0;
+}
+
+static void tegra2_clk_m_disable(struct clk *c)
+{
+ BUG();
+}
+
+static struct clk_ops tegra_clk_m_ops = {
+ .init = tegra2_clk_m_init,
+ .enable = tegra2_clk_m_enable,
+ .disable = tegra2_clk_m_disable,
+ .get_rate = tegra2_clk_get_rate,
+};
+
+/* PLL Functions */
+static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ u32 reg;
+ unsigned long input_rate;
+ const struct clk_pll_table *sel;
+
+ input_rate = clk_get_rate(c->parent);
+ for (sel = c->pll_table; sel->input_rate != 0; sel++) {
+ if (sel->input_rate == input_rate && sel->output_rate == rate) {
+ c->n = sel->n;
+ c->m = sel->m;
+ c->p = sel->p;
+ c->cpcon = sel->cpcon;
+ reg = clk_readl(c->reg);
+ if (c->flags & PLL_FIXED)
+ reg |= 1<<28;
+ reg &= ~0x7FFF;
+ reg |= (c->m << 0) | (c->n << 8);
+ BUG_ON(c->p > 2);
+ if (c->p == 2)
+ reg |= 1<<20;
+ clk_writel(reg, c->reg);
+ c->rate = rate;
+
+ if (c->flags & PLL_HAS_CPCON) {
+ reg = c->cpcon << 8;
+ clk_writel(reg, c->reg+0xC);
+ }
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int tegra2_pll_clk_enable(struct clk *c)
+{
+ int ret = 0;
+ u32 reg;
+
+ reg = clk_readl(c->reg);
+ reg &= ~(1 << 31);
+ reg |= 1 << 30;
+ clk_writel(reg, c->reg);
+ return ret;
+}
+
+static void tegra2_pll_clk_disable(struct clk *c)
+{
+ u32 reg;
+
+ reg = clk_readl(c->reg);
+ reg &= ~(1 << 31);
+ reg &= ~(1 << 30);
+ clk_writel(reg, c->reg);
+}
+
+static struct clk_ops tegra_pll_ops = {
+ .enable = tegra2_pll_clk_enable,
+ .disable = tegra2_pll_clk_disable,
+ .set_rate = tegra2_pll_clk_set_rate,
+ .get_rate = tegra2_clk_get_rate,
+};
+
+/* Clock divider ops */
+static int tegra2_div_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ int ret = 0;
+ u32 reg;
+ u32 new_reg;
+ int divider_u71;
+
+ if (c->flags & DIV_U71) {
+ divider_u71 = clk_div71_possible_rate(c->parent, rate);
+ if (divider_u71 >= 0) {
+ reg = clk_readl(c->reg);
+ new_reg = reg >> c->reg_shift;
+ new_reg &= 0xFFFF;
+
+ if (c->flags & DIV_U71_FIXED)
+ new_reg &= ~(1<<2);
+ new_reg &= ~(0xFF);
+ new_reg |= divider_u71;
+
+ reg &= ~(0xFFFF << c->reg_shift);
+ reg |= new_reg << c->reg_shift;
+ clk_writel(reg, c->reg);
+ return 1;
+ }
+ } else if (c->flags & DIV_2) {
+ if (clk_get_rate(c->parent) == rate * 2)
+ return 1;
+ }
+ BUG();
+ return ret;
+}
+
+
+static struct clk_ops tegra_div_ops = {
+ .enable = tegra2_clk_enable,
+ .disable = tegra2_clk_disable,
+ .set_rate = tegra2_div_clk_set_rate,
+ .get_rate = tegra2_clk_get_rate,
+};
+
+/* Periph clk ops */
+static void tegra2_periph_clk_init(struct clk *c)
+{
+ clk_set_parent(c, c->inputs[0].input);
+}
+
+static int tegra2_periph_clk_enable(struct clk *c)
+{
+ u32 reg, bit;
+
+ reg = (1 << (c->clk_num % 32));
+ bit = (c->clk_num / 32) << 3;
+
+ clk_writel(reg, CLK_RST_CONTROLLER_CLK_OUT_ENB_SET_CLR | bit);
+ clk_writel(reg, CLK_RST_CONTROLLER_RST_DEVICES_SET_CLR | bit | 4);
+ return 0;
+}
+
+static void tegra2_periph_clk_disable(struct clk *c)
+{
+ u32 reg, bit;
+
+ reg = (1 << (c->clk_num % 32));
+ bit = (c->clk_num / 32) << 3;
+
+ clk_writel(reg, CLK_RST_CONTROLLER_CLK_OUT_ENB_SET_CLR | bit | 4);
+ clk_writel(reg, CLK_RST_CONTROLLER_RST_DEVICES_SET_CLR | bit);
+}
+
+static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
+{
+ int ret = 0;
+ u32 reg;
+ const struct clk_mux_sel *sel;
+ for (sel = c->inputs; sel->input != NULL; sel++) {
+ if (sel->input == p) {
+ c->parent = p;
+ reg = clk_readl(c->reg);
+ reg &= ~(0x3<<30);
+ reg |= (sel->value)<<30;
+ clk_writel(reg, c->reg);
+ }
+ }
+
+ return ret;
+}
+
+static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ int ret = 0;
+ u32 reg;
+ int divider_u71;
+ const struct clk_mux_sel *sel;
+
+ for (sel = c->inputs; sel->input != NULL; sel++) {
+ if (c->flags & DIV_U71) {
+ divider_u71 = clk_div71_possible_rate(sel->input, rate);
+ if (divider_u71 >= 0) {
+ /* FIXME: ensure we don't have too high rate */
+ clk_set_parent(c, sel->input);
+ udelay(1);
+ reg = clk_readl(c->reg);
+ reg &= ~(0xFF);
+ reg |= divider_u71;
+ clk_writel(reg, c->reg);
+ return 1;
+ }
+ } else {
+ if (clk_get_rate(sel->input) == rate) {
+ clk_set_parent(c, sel->input);
+ return 1;
+ }
+ }
+ }
+ BUG();
+ return ret;
+}
+
+static struct clk_ops tegra_periph_clk_ops = {
+ .init = &tegra2_periph_clk_init,
+ .enable = &tegra2_periph_clk_enable,
+ .disable = &tegra2_periph_clk_disable,
+ .set_parent = &tegra2_periph_clk_set_parent,
+ .set_rate = &tegra2_periph_clk_set_rate,
+};
+
+static struct clk tegra_clk_32k = {
+ .name = "tegra_clk_32k",
+ .rate = 32678,
+ .ops = NULL,
+};
+
+static struct clk tegra_clk_input = {
+ .name = "tegra_clk_input",
+ .flags = ENABLE_ON_INIT,
+ .rate = 12000000,
+ .ops = NULL,
+};
+
+static struct clk_pll_table tegra_pll_s_table[] = {
+ {32768, 12000000, 366, 1, 1, 0},
+ {32768, 13000000, 397, 1, 1, 0},
+ {32768, 19200000, 586, 1, 1, 0},
+ {32768, 26000000, 793, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0},
+};
+
+static struct clk tegra_pll_s = {
+ .name = "tegra_pll_s",
+ .ops = &tegra_pll_ops,
+ .reg = 0xf0,
+ .input_min = 32768,
+ .input_max = 32768,
+ .parent = &tegra_clk_32k,
+ .cf_min = 0, /* FIXME */
+ .cf_max = 0, /* FIXME */
+ .vco_min = 12000000,
+ .vco_max = 26000000,
+ .pll_table = tegra_pll_s_table,
+};
+
+static struct clk_mux_sel tegra_clk_m_sel[] = {
+ { .input = &tegra_clk_32k, .value = 0},
+ { .input = &tegra_pll_s, .value = 1},
+ { 0, 0},
+};
+
+static struct clk tegra_clk_m = {
+ .name = "tegra_clk_m",
+ .flags = ENABLE_ON_INIT,
+ .ops = &tegra_clk_m_ops,
+ .inputs = tegra_clk_m_sel,
+ .reg = 0x1fc,
+ .reg_mask = (1<<28),
+ .reg_shift = 28,
+};
+
+static struct clk_pll_table tegra_pll_c_table[] = {
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_c = {
+ .name = "tegra_pll_c",
+ .flags = PLL_HAS_CPCON,
+ .ops = &tegra_pll_ops,
+ .reg = 0x80,
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .parent = &tegra_clk_m,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 20000000,
+ .vco_max = 1400000000,
+ .pll_table = tegra_pll_c_table,
+};
+
+static struct clk tegra_pll_c_out1 = {
+ .name = "tegra_pll_c_out1",
+ .ops = &tegra_div_ops,
+ .flags = DIV_U71,
+ .parent = &tegra_pll_c,
+ .reg = 0x84,
+ .reg_shift = 0,
+};
+
+static struct clk_pll_table tegra_pll_m_table[] = {
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_m = {
+ .name = "tegra_pll_m",
+ .flags = PLL_HAS_CPCON,
+ .ops = &tegra_pll_ops,
+ .reg = 0x90,
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .parent = &tegra_clk_m,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 20000000,
+ .vco_max = 1200000000,
+ .pll_table = tegra_pll_m_table,
+};
+
+static struct clk tegra_pll_m_out1 = {
+ .name = "tegra_pll_m_out1",
+ .ops = &tegra_div_ops,
+ .flags = DIV_U71,
+ .parent = &tegra_pll_m,
+ .reg = 0x94,
+ .reg_shift = 0,
+};
+
+static struct clk_pll_table tegra_pll_p_table[] = {
+ { 12000000, 216000000, 432, 12, 2, 8},
+ { 13000000, 216000000, 432, 13, 2, 8},
+ { 19200000, 216000000, 90, 4, 2, 1},
+ { 26000000, 216000000, 432, 26, 2, 8},
+ { 12000000, 432000000, 432, 12, 1, 8},
+ { 13000000, 432000000, 432, 13, 1, 8},
+ { 19200000, 432000000, 90, 4, 1, 1},
+ { 26000000, 432000000, 432, 26, 1, 8},
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_p = {
+ .name = "tegra_pll_p",
+ .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
+ .ops = &tegra_pll_ops,
+ .reg = 0xa0,
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .parent = &tegra_clk_m,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 20000000,
+ .vco_max = 1400000000,
+ .pll_table = tegra_pll_p_table,
+};
+
+static struct clk tegra_pll_p_out1 = {
+ .name = "tegra_pll_p_out1",
+ .ops = &tegra_div_ops,
+ .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+ .parent = &tegra_pll_p,
+ .reg = 0xa4,
+ .reg_shift = 0,
+};
+
+static struct clk tegra_pll_p_out2 = {
+ .name = "tegra_pll_p_out2",
+ .ops = &tegra_div_ops,
+ .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+ .parent = &tegra_pll_p,
+ .reg = 0xa4,
+ .reg_shift = 16,
+};
+
+static struct clk tegra_pll_p_out3 = {
+ .name = "tegra_pll_p_out3",
+ .ops = &tegra_div_ops,
+ .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+ .parent = &tegra_pll_p,
+ .reg = 0xa8,
+ .reg_shift = 0,
+};
+
+static struct clk tegra_pll_p_out4 = {
+ .name = "tegra_pll_p_out4",
+ .ops = &tegra_div_ops,
+ .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+ .parent = &tegra_pll_p,
+ .reg = 0xa8,
+ .reg_shift = 16,
+};
+
+static struct clk_pll_table tegra_pll_a_table[] = {
+ { 28800000, 56448000, 49, 25, 1, 1},
+ { 28800000, 73728000, 64, 25, 1, 1},
+ { 28800000, 11289600, 49, 25, 1, 1},
+ { 28800000, 12288000, 64, 25, 1, 1},
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_a = {
+ .name = "tegra_pll_a",
+ .flags = PLL_HAS_CPCON,
+ .ops = &tegra_pll_ops,
+ .reg = 0xb0,
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .parent = &tegra_pll_p_out1,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 20000000,
+ .vco_max = 1400000000,
+ .pll_table = tegra_pll_a_table,
+};
+
+static struct clk tegra_pll_a_out0 = {
+ .name = "tegra_pll_a_out0",
+ .ops = &tegra_div_ops,
+ .flags = DIV_U71,
+ .parent = &tegra_pll_a,
+ .reg = 0xb4,
+ .reg_shift = 0,
+};
+
+static struct clk_pll_table tegra_pll_d_table[] = {
+ { 12000000, 1000000000, 1000, 12, 1, 12},
+ { 13000000, 1000000000, 1000, 13, 1, 12},
+ { 19200000, 1000000000, 625, 12, 1, 8},
+ { 26000000, 1000000000, 1000, 26, 1, 12},
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_d = {
+ .name = "tegra_pll_d",
+ .flags = PLL_HAS_CPCON,
+ .ops = &tegra_pll_ops,
+ .reg = 0xd0,
+ .input_min = 2000000,
+ .input_max = 40000000,
+ .parent = &tegra_clk_m,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 40000000,
+ .vco_max = 1000000000,
+ .pll_table = tegra_pll_d_table,
+};
+
+static struct clk tegra_pll_d_out0 = {
+ .name = "tegra_pll_d_out0",
+ .ops = &tegra_div_ops,
+ .flags = DIV_2,
+ .parent = &tegra_pll_d,
+};
+
+static struct clk_pll_table tegra_pll_u_table[] = {
+ { 12000000, 480000000, 960, 12, 1, 0},
+ { 13000000, 480000000, 960, 13, 1, 0},
+ { 19200000, 480000000, 200, 4, 1, 0},
+ { 26000000, 480000000, 960, 26, 1, 0},
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_u = {
+ .name = "tegra_pll_u",
+ .flags = 0,
+ .ops = &tegra_pll_ops,
+ .reg = 0xc0,
+ .input_min = 2000000,
+ .input_max = 40000000,
+ .parent = &tegra_clk_m,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 480000000,
+ .vco_max = 960000000,
+ .pll_table = tegra_pll_u_table,
+};
+
+static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
+ { .input = &tegra_pll_m, .value = 0},
+ { .input = &tegra_pll_c, .value = 1},
+ { .input = &tegra_pll_p, .value = 2},
+ { .input = &tegra_pll_a_out0, .value = 3},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
+ { .input = &tegra_pll_p, .value = 0},
+ { .input = &tegra_pll_c, .value = 1},
+ { .input = &tegra_pll_m, .value = 2},
+ { .input = &tegra_clk_m, .value = 3},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_plla_audio_pllp_clkm[] = {
+ {.input = &tegra_pll_a, .value = 0},
+ /* FIXME: no mux defined for tegra_audio
+ {.input = &tegra_audio, .value = 1},*/
+ {.input = &tegra_pll_p, .value = 2},
+ {.input = &tegra_clk_m, .value = 3},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
+ {.input = &tegra_pll_p, .value = 0},
+ {.input = &tegra_pll_d_out0, .value = 1},
+ {.input = &tegra_pll_c, .value = 2},
+ {.input = &tegra_clk_m, .value = 3},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_audio_clkm_clk32[] = {
+ {.input = &tegra_pll_p, .value = 0},
+ {.input = &tegra_pll_c, .value = 1},
+ /* FIXME: no mux defined for tegra_audio
+ {.input = &tegra_audio, .value = 2},*/
+ {.input = &tegra_clk_m, .value = 3},
+ {.input = &tegra_clk_32k, .value = 4},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_pllm[] = {
+ {.input = &tegra_pll_p, .value = 0},
+ {.input = &tegra_pll_c, .value = 1},
+ {.input = &tegra_pll_m, .value = 2},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_clk_m[] = {
+ { .input = &tegra_clk_m, .value = 0},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_clk_32k[] = {
+ { .input = &tegra_clk_32k, .value = 0},
+ { 0, 0},
+};
+
+#define PERIPH_CLK(_name, _clk_num, _reg, _inputs, _flags) \
+ struct clk clk_##_name = { \
+ .name = __stringify(_name), \
+ .ops = &tegra_periph_clk_ops, \
+ .clk_num = _clk_num, \
+ .reg = _reg, \
+ .inputs = _inputs, \
+ .flags = _flags, \
+ }
+
+#define PERIPH_CLK_U71(_name, _clk_num, _reg, _inputs) \
+ PERIPH_CLK(_name, _clk_num, _reg, _inputs, MUX | DIV_U71)
+
+static PERIPH_CLK(rtc, 4, 0, mux_clk_32k, 0);
+static PERIPH_CLK(usbd, 22, 0, mux_clk_m, 0);
+static PERIPH_CLK(usb2, 58, 0, mux_clk_m, 0);
+static PERIPH_CLK(usb3, 59, 0, mux_clk_m, 0);
+static PERIPH_CLK(timer, 5, 0, mux_clk_m, 0);
+
+static PERIPH_CLK_U71(i2s1, 11, 0x100, mux_plla_audio_pllp_clkm);
+static PERIPH_CLK_U71(i2s2, 18, 0x104, mux_plla_audio_pllp_clkm);
+static PERIPH_CLK_U71(spdif_in, 10, 0x10c, mux_pllp_pllc_pllm);
+static PERIPH_CLK_U71(spdif_out, 10, 0x108, mux_plla_audio_pllp_clkm);
+static PERIPH_CLK_U71(pwm, 17, 0x110, mux_pllp_pllc_audio_clkm_clk32);
+static PERIPH_CLK_U71(spi, 43, 0x114, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(xio, 45, 0x120, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(twc, 16, 0x12c, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(sbc1, 41, 0x134, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(sbc2, 44, 0x118, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(sbc3, 46, 0x11c, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(sbc4, 68, 0x1b4, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(ide, 25, 0x144, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(ndflash, 13, 0x160, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(vfir, 7, 0x168, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(sdmmc1, 14, 0x150, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(sdmmc2, 9, 0x154, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(sdmmc3, 69, 0x1bc, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(sdmmc4, 15, 0x160, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(vde, 61, 0x1c8, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(csite, 73, 0x1d4, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(la, 76, 0x1f8, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(owr, 71, 0x1cc, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(nor, 42, 0x1d0, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(mipi, 50, 0x174, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(i2c1, 12, 0x124, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(i2c2, 54, 0x198, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(i2c3, 67, 0x1b8, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(dvc, 47, 0x128, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(uarta, 6, 0x178, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(uartb, 7, 0x17c, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(uartc, 55, 0x1a0, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(uartd, 65, 0x1c0, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(uarte, 66, 0x1c4, mux_pllp_pllc_pllm_clkm);
+static PERIPH_CLK_U71(3d, 24, 0x158, mux_pllm_pllc_pllp_plla);
+static PERIPH_CLK_U71(2d, 21, 0x15c, mux_pllm_pllc_pllp_plla);
+static PERIPH_CLK_U71(vi, 20, 0x148, mux_pllm_pllc_pllp_plla);
+static PERIPH_CLK_U71(vi_sensor, 20, 0x1a8, mux_pllm_pllc_pllp_plla);
+static PERIPH_CLK_U71(epp, 19, 0x16c, mux_pllm_pllc_pllp_plla);
+static PERIPH_CLK_U71(mpe, 60, 0x170, mux_pllm_pllc_pllp_plla);
+static PERIPH_CLK_U71(host1x, 28, 0x180, mux_pllm_pllc_pllp_plla);
+static PERIPH_CLK_U71(cve, 49, 0x140, mux_pllp_plld_pllc_clkm);
+static PERIPH_CLK_U71(tvo, 49, 0x188, mux_pllp_plld_pllc_clkm);
+static PERIPH_CLK_U71(hdmi, 51, 0x18c, mux_pllp_plld_pllc_clkm);
+static PERIPH_CLK_U71(tvdac, 53, 0x194, mux_pllp_plld_pllc_clkm);
+static PERIPH_CLK_U71(disp1, 27, 0x138, mux_pllp_plld_pllc_clkm);
+static PERIPH_CLK_U71(disp2, 26, 0x13c, mux_pllp_plld_pllc_clkm);
+
+#define CLK(dev, con, ck) \
+ { \
+ .dev_id = dev, \
+ .con_id = con, \
+ .clk = ck, \
+ }
+
+struct clk_lookup tegra_clk_lookups[] = {
+ /* external root sources */
+ CLK(NULL, "input_clk", &tegra_clk_input),
+ CLK(NULL, "32k_clk", &tegra_clk_32k),
+ CLK(NULL, "clk_m", &tegra_clk_m),
+
+ /* PLLs */
+ CLK(NULL, "pll_a", &tegra_pll_a),
+ CLK(NULL, "pll_c", &tegra_pll_c),
+ CLK(NULL, "pll_d", &tegra_pll_d),
+ CLK(NULL, "pll_m", &tegra_pll_m),
+ CLK(NULL, "pll_p", &tegra_pll_p),
+ CLK(NULL, "pll_s", &tegra_pll_s),
+ CLK(NULL, "pll_u", &tegra_pll_u),
+
+ /* PLL outputs */
+ CLK(NULL, "pll_a_out0", &tegra_pll_a_out0),
+ CLK(NULL, "pll_c_out1", &tegra_pll_c_out1),
+ CLK(NULL, "pll_d_out0", &tegra_pll_d_out0),
+ CLK(NULL, "pll_m_out1", &tegra_pll_m_out1),
+ CLK(NULL, "pll_p_out1", &tegra_pll_p_out1),
+ CLK(NULL, "pll_p_out2", &tegra_pll_p_out2),
+ CLK(NULL, "pll_p_out3", &tegra_pll_p_out3),
+ CLK(NULL, "pll_p_out4", &tegra_pll_p_out4),
+
+ /* peripheral clocks */
+ CLK("rtc-tegra", NULL, &clk_rtc),
+ CLK("timer", NULL, &clk_timer),
+ CLK("i2s.0", NULL, &clk_i2s1),
+ CLK("i2s.1", NULL, &clk_i2s2),
+ CLK("spdif_out", NULL, &clk_spdif_out),
+ CLK("spdif_in", NULL, &clk_spdif_in),
+ CLK("pwm", NULL, &clk_pwm),
+ CLK("spi", NULL, &clk_spi),
+ CLK("xio", NULL, &clk_xio),
+ CLK("twc", NULL, &clk_twc),
+ CLK("sbc.0", NULL, &clk_sbc1),
+ CLK("sbc.1", NULL, &clk_sbc2),
+ CLK("sbc.2", NULL, &clk_sbc3),
+ CLK("sbc.3", NULL, &clk_sbc4),
+ CLK("ide", NULL, &clk_ide),
+ CLK("tegra_nand", NULL, &clk_ndflash),
+ CLK("vfir", NULL, &clk_vfir),
+ CLK("sdmmc.0", NULL, &clk_sdmmc1),
+ CLK("sdmmc.1", NULL, &clk_sdmmc2),
+ CLK("sdmmc.2", NULL, &clk_sdmmc3),
+ CLK("sdmmc.3", NULL, &clk_sdmmc4),
+ CLK("vde", NULL, &clk_vde),
+ CLK("csite", NULL, &clk_csite),
+ CLK("la", NULL, &clk_la),
+ CLK("owr", NULL, &clk_owr),
+ CLK("nor", NULL, &clk_nor),
+ CLK("mipi", NULL, &clk_mipi),
+ CLK("i2c.0", NULL, &clk_i2c1),
+ CLK("i2c.1", NULL, &clk_i2c2),
+ CLK("i2c.2", NULL, &clk_i2c3),
+ CLK("dvc", NULL, &clk_dvc),
+ CLK("uart.0", NULL, &clk_uarta),
+ CLK("uart.1", NULL, &clk_uartb),
+ CLK("uart.2", NULL, &clk_uartc),
+ CLK("uart.3", NULL, &clk_uartd),
+ CLK("uart.4", NULL, &clk_uarte),
+ CLK("3d", NULL, &clk_3d),
+ CLK("2d", NULL, &clk_2d),
+ CLK("vi", NULL, &clk_vi),
+ CLK("vi_sensor", NULL, &clk_vi_sensor),
+ CLK("epp", NULL, &clk_epp),
+ CLK("mpe", NULL, &clk_mpe),
+ CLK("host1x", NULL, &clk_host1x),
+ CLK("cve", NULL, &clk_cve),
+ CLK("tvo", NULL, &clk_tvo),
+ CLK("hdmi", NULL, &clk_hdmi),
+ CLK("tvdac", NULL, &clk_tvdac),
+ CLK("tegrafb.0", NULL, &clk_disp1),
+ CLK("tegrafb.1", NULL, &clk_disp2),
+ CLK("usb.0", NULL, &clk_usbd),
+ CLK("usb.1", NULL, &clk_usb2),
+ CLK("usb.2", NULL, &clk_usb3),
+};
+
+int __init tegra_init_clock(void)
+{
+ int i;
+ struct clk_lookup *cl;
+
+ reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
+
+ for (i = 0; i < ARRAY_SIZE(tegra_clk_lookups); i++) {
+ cl = &tegra_clk_lookups[i];
+ if (cl->clk->ops && cl->clk->ops->init)
+ cl->clk->ops->init(cl->clk);
+ clkdev_add(cl);
+
+ if (cl->clk->flags & ENABLE_ON_INIT)
+ clk_enable(cl->clk);
+ }
+
+ return 0;
+}
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c
new file mode 100644
index 0000000..a82f808
--- /dev/null
+++ b/arch/arm/mach-tegra/timer.c
@@ -0,0 +1,182 @@
+/*
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/clk.h>
+#include <asm/mach/time.h>
+#include <asm/io.h>
+#include <asm/mach/time.h>
+#include <asm/localtimer.h>
+
+#include <mach/hardware.h>
+
+#define TIMERUS_CNTR_1US 0x10
+#define TIMERUS_USEC_CFG 0x14
+#define TIMERUS_CNTR_FREEZE 0x4c
+
+#define TIMER1_BASE 0x0
+#define TIMER2_BASE 0x8
+#define TIMER3_BASE 0x50
+#define TIMER4_BASE 0x58
+
+#define TIMER_PTV 0x0
+#define TIMER_PCR 0x4
+
+#define TIMER1_IRQ 32
+#define TIMER2_IRQ 33
+#define TIMER3_IRQ 41
+#define TIMER4_IRQ 42
+
+struct tegra_timer;
+
+static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE);
+
+#define timer_writel(value, reg) \
+ __raw_writel(value, (u32)timer_reg_base + (reg))
+#define timer_readl(reg) \
+ __raw_readl((u32)timer_reg_base + (reg))
+
+static int tegra_timer_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ u32 reg;
+
+ reg = 0x80000000 | ((1000000/HZ)*(cycles+1)-1);
+ timer_writel(reg, TIMER1_BASE + TIMER_PTV);
+
+ return 0;
+}
+
+static void tegra_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ u32 reg;
+
+ timer_writel(0, TIMER1_BASE + TIMER_PTV);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ reg = 0xC0000000 | ((1000000/HZ)-1);
+ timer_writel(reg, TIMER1_BASE + TIMER_PTV);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static cycle_t tegra_clocksource_read(struct clocksource *cs)
+{
+ return timer_readl(TIMERUS_CNTR_1US);
+}
+
+static struct clock_event_device tegra_clockevent = {
+ .name = "timer0",
+ .rating = 300,
+ .features = CLOCK_EVT_FEAT_ONESHOT, CLOCK_EVT_FEAT_PERIODIC,
+ .mult = 16777,
+ .shift = 24,
+ .set_next_event = tegra_timer_set_next_event,
+ .set_mode = tegra_timer_set_mode,
+};
+
+static struct clocksource tegra_clocksource = {
+ .name = "timer_us",
+ .rating = 300,
+ .read = tegra_clocksource_read,
+ .mask = 0xFFFFFFFFUL,
+ .mult = 1000,
+ .shift = 0,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+ timer_writel(1<<30, TIMER1_BASE + TIMER_PCR);
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction tegra_timer_irq = {
+ .name = "timer0",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_HIGH,
+ .handler = tegra_timer_interrupt,
+ .dev_id = &tegra_clockevent,
+ .irq = TIMER1_IRQ,
+};
+
+static void __init tegra_init_timer(void)
+{
+ struct clk *c;
+ int ret;
+
+#ifdef CONFIG_HAVE_ARM_TWD
+ twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600);
+#endif
+
+ c = clk_get_sys("timer", NULL);
+ pr_info("Timer clock rate %lu\n", clk_get_rate(c));
+
+ switch (clk_get_rate(c)) {
+ case 12000000:
+ timer_writel(0x000b, TIMERUS_USEC_CFG);
+ break;
+ case 13000000:
+ timer_writel(0x000c, TIMERUS_USEC_CFG);
+ break;
+ case 19200000:
+ timer_writel(0x045f, TIMERUS_USEC_CFG);
+ break;
+ case 26000000:
+ timer_writel(0x0019, TIMERUS_USEC_CFG);
+ break;
+ default:
+ WARN(1, "Unknown clock rate");
+ }
+
+ if (clocksource_register(&tegra_clocksource)) {
+ printk(KERN_ERR "Failed to register clocksource\n");
+ BUG();
+ }
+
+ ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq);
+ if (ret) {
+ printk(KERN_ERR "Failed to register timer IRQ: %d\n", ret);
+ BUG();
+ }
+
+ tegra_clockevent.max_delta_ns =
+ clockevent_delta2ns(0x1fffffff, &tegra_clockevent);
+ tegra_clockevent.max_delta_ns =
+ clockevent_delta2ns(0x1, &tegra_clockevent);
+ tegra_clockevent.cpumask = cpu_all_mask;
+ tegra_clockevent.irq = TIMER1_IRQ;
+ clockevents_register_device(&tegra_clockevent);
+
+ return;
+}
+
+struct sys_timer tegra_timer = {
+ .init = tegra_init_timer,
+};
--
1.6.4.4
--
Sincerely yours,
Mike.
^ permalink raw reply related [flat|nested] 37+ messages in thread* [RFC/PATCH] ARM: add Tegra support 2010-03-09 16:38 [RFC/PATCH] ARM: add Tegra support Mike Rapoport @ 2010-03-14 6:51 ` Mike Rapoport 2010-03-15 6:54 ` Thierry Reding 2010-03-15 17:41 ` Gary King ` (2 subsequent siblings) 3 siblings, 1 reply; 37+ messages in thread From: Mike Rapoport @ 2010-03-14 6:51 UTC (permalink / raw) To: linux-arm-kernel Mike Rapoport wrote: > This patch adds basic support for Nvidia Tegra2 platform. > > From 13fac106b9383478a3337e443a946286998536d7 Mon Sep 17 00:00:00 2001 > From: Mike Rapoport <mike@compulab.co.il> > Date: Tue, 9 Mar 2010 18:35:45 +0200 > Subject: [PATCH] ARM: add Tegra support > > Signed-off-by: Mike Rapoport <mike@compulab.co.il> > --- Any comments on this? -- Sincerely yours, Mike. ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH] ARM: add Tegra support 2010-03-14 6:51 ` Mike Rapoport @ 2010-03-15 6:54 ` Thierry Reding 2010-03-15 16:16 ` Thierry Reding 0 siblings, 1 reply; 37+ messages in thread From: Thierry Reding @ 2010-03-15 6:54 UTC (permalink / raw) To: linux-arm-kernel * Mike Rapoport wrote: > Mike Rapoport wrote: > >This patch adds basic support for Nvidia Tegra2 platform. > > > > From 13fac106b9383478a3337e443a946286998536d7 Mon Sep 17 00:00:00 2001 > >From: Mike Rapoport <mike@compulab.co.il> > >Date: Tue, 9 Mar 2010 18:35:45 +0200 > >Subject: [PATCH] ARM: add Tegra support > > > >Signed-off-by: Mike Rapoport <mike@compulab.co.il> > >--- > > Any comments on this? I like it. I will try to get around to test this today. Thierry -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: Digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100315/116fea53/attachment.sig> ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH] ARM: add Tegra support 2010-03-15 6:54 ` Thierry Reding @ 2010-03-15 16:16 ` Thierry Reding 0 siblings, 0 replies; 37+ messages in thread From: Thierry Reding @ 2010-03-15 16:16 UTC (permalink / raw) To: linux-arm-kernel * Thierry Reding wrote: > * Mike Rapoport wrote: > > Mike Rapoport wrote: > > >This patch adds basic support for Nvidia Tegra2 platform. > > > > > > From 13fac106b9383478a3337e443a946286998536d7 Mon Sep 17 00:00:00 2001 > > >From: Mike Rapoport <mike@compulab.co.il> > > >Date: Tue, 9 Mar 2010 18:35:45 +0200 > > >Subject: [PATCH] ARM: add Tegra support > > > > > >Signed-off-by: Mike Rapoport <mike@compulab.co.il> > > >--- > > > > Any comments on this? > > I like it. I will try to get around to test this today. So this seems to work well. I'm able to boot a kernel built with this patch and run a basic initial ramdisk. Do you have any kind of roadmap of what you are currently working on? I'd rather not duplicate any work you're already doing. Thierry ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH] ARM: add Tegra support 2010-03-09 16:38 [RFC/PATCH] ARM: add Tegra support Mike Rapoport 2010-03-14 6:51 ` Mike Rapoport @ 2010-03-15 17:41 ` Gary King 2010-03-15 18:09 ` Russell King - ARM Linux 2010-03-15 22:38 ` Erik Gilling 3 siblings, 0 replies; 37+ messages in thread From: Gary King @ 2010-03-15 17:41 UTC (permalink / raw) To: linux-arm-kernel Hi Mike, Hopefully I've quoted enough context to associate the comments below back to their original source: > --- /dev/null > +++ b/arch/arm/mach-tegra/clock.c > ... > + } > + } > + c->refcnt++; > +err: The reference counting in this file is not thread safe. > --- /dev/null > +++ b/arch/arm/mach-tegra/tegra2_clocks.c > ... > +/* clk_m functions */ > +static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c) > +{ > + u32 clk_autodetect; > + u32 auto_clk_ctl = clk_readl(0x50) & ~(3<<30); > + > ... > +} The switch statement here doesn't provide enough tolerance for variability in the source oscillator or crystal; there should be a range of +-2-3 units to cover variability & jitter. > --- /dev/null > +++ b/arch/arm/mach-tegra/gpio.c > ... > +static int tegra_gpio_irq_set_type(unsigned int irq, unsigned int type) > +{ > + int gpio = irq - INT_GPIO_BASE; > + struct tegra_gpio_bank *bank = get_irq_data(irq); > + int port = GPIO_PORT(gpio); This should be get_irq_chip_data(irq) > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/uncompress.h > ... > + > +static void putc(int c) > +{ > + volatile u8 *uart = (volatile u8 *)(TEGRA_UARTD_BASE); > + int shift = 2; UARTD as the serial console is Harmony-specific; the specific UART should either be protected by a MACH_HARMONY ifdef or hoisted to a MACH_HARMONY-only header-file. > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/debug-macro.S > ... > + ldrne \rx, =IO_APB_VIRT @ virtual > + orr \rx, \rx, #0x6300 @ UART D > + .endm Same comment as above re: UARTD. - Gary ----------------------------------------------------------------------------------- This email message is for the sole use of the intended recipient(s) and may contain confidential information. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message. ----------------------------------------------------------------------------------- ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH] ARM: add Tegra support 2010-03-09 16:38 [RFC/PATCH] ARM: add Tegra support Mike Rapoport 2010-03-14 6:51 ` Mike Rapoport 2010-03-15 17:41 ` Gary King @ 2010-03-15 18:09 ` Russell King - ARM Linux 2010-03-15 22:38 ` Erik Gilling 3 siblings, 0 replies; 37+ messages in thread From: Russell King - ARM Linux @ 2010-03-15 18:09 UTC (permalink / raw) To: linux-arm-kernel On Tue, Mar 09, 2010 at 06:38:36PM +0200, Mike Rapoport wrote: > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > index 3b18128..d479cd8 100644 > --- a/arch/arm/Kconfig > +++ b/arch/arm/Kconfig > @@ -750,6 +750,17 @@ config ARCH_U8500 > help > Support for ST-Ericsson's Ux500 architecture > > +config ARCH_TEGRA > + bool "NVIDIA Tegra" > + select GENERIC_TIME > + select GENERIC_CLOCKEVENTS > + select GENERIC_GPIO > + select HAVE_CLK > + select COMMON_CLKDEV > + help > + This enables support for NVIDIA Tegra based systems (Tegra APX, > + Tegra 6xx and Tegra 2 series). > + Please don't blindly add to the end of a sorted list; this causes disgusting merge conflicts. Please add to the correct place in the list instead. "NVIDIA" belongs after "Nuvoton NUC93X CPU" but before "Philips Nexperia PNX4008 Mobile". > +static struct platform_device debug_uart = { > + .name = "serial8250", > + .id = 0, PLAT8250_DEV_xxx please. > +static void __init tegra_harmony_fixup(struct machine_desc *desc, > + struct tag *tags, > + char **cmdline, struct meminfo *mi) > +{ > + mi->nr_banks = 2; > + mi->bank[0].start = PHYS_OFFSET; > + mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET); > + mi->bank[0].size = (448*1024*1024); Parens aren't required. > diff --git a/arch/arm/mach-tegra/include/mach/vmalloc.h b/arch/arm/mach-tegra/include/mach/vmalloc.h > new file mode 100644 > index 0000000..33444b1 > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/vmalloc.h > @@ -0,0 +1,22 @@ > +/* > + * arch/arm/mach-tegra/include/mach/vmalloc.h > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * 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. > + * > + */ > + > +#ifndef __MACH_TEGRA_VMALLOC_H > +#define __MACH_TEGRA_VMALLOC_H > + > +#define VMALLOC_END ((PAGE_OFFSET) + 0x38000000) So if PAGE_OFFSET were to be 0xe0000000, this would still be valid? And what if PAGE_OFFSET were 0x80000000 ? Wouldn't it be better to define it in terms of the maximum address as defined by the hardware maps - so that selecting 2GB of userspace gives you more kernel space? ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH] ARM: add Tegra support 2010-03-09 16:38 [RFC/PATCH] ARM: add Tegra support Mike Rapoport ` (2 preceding siblings ...) 2010-03-15 18:09 ` Russell King - ARM Linux @ 2010-03-15 22:38 ` Erik Gilling 2010-03-16 6:41 ` [RFC/PATCH 00/10] Tegra2 support konkers at google.com 2010-03-16 8:49 ` [RFC/PATCH] ARM: add Tegra support Mike Rapoport 3 siblings, 2 replies; 37+ messages in thread From: Erik Gilling @ 2010-03-15 22:38 UTC (permalink / raw) To: linux-arm-kernel On Tue, Mar 9, 2010 at 9:38 AM, Mike Rapoport <mike@compulab.co.il> wrote: > This patch adds basic support for Nvidia Tegra2 platform. This code seems to be our port from git://android.git.kernel.org/kernel/tegra.git with some features removed, minor cleanups, and many trivial changes. These changes make it difficult for us to track improvements and bug fixes in either direction. We're happy that other people are interested in our work however are disappointed that our opinions were not sought before making these changes and posting nor was any attribution given to the work's authors. We're still in the process here at Google of cleaning up the port for submission. We should have our changes rebased on 34-rc1 without the android-common code by the end of the day. We've been maintaining a patchstack which separates out the functional subsystems. Would people here prefer to see that or a collapsed patch like this one. Specific issues with this patch with respect to our work: Lots of trival changes like moving files around, renaming variables, and re-wording/re-formating comments (sometimes changing the meaning of the comment incorrectly) Removal of SMP, L2 cache, and pinmux support. Removal of the gpio_names header. Because tegra does not define GPIOs numerically, it is impossible to convert a gpio name (i.e. PN6) from a schematic to a GPIO number without consulting and interpreting the datasheet. Removal of the tegra_gpio_enable and tegra_gpio_disable functions. Because of the way pin muxing is implemented in tegra, gpio configuration does not map into the pinmuxing subsystem. Removal of pr_debug lines from the clock code. Changing the way peripheral clocks are defined to use two separate tables which are required to be kept in sync by hand. Removal of some pll entries. -Erik ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 00/10] Tegra2 support 2010-03-15 22:38 ` Erik Gilling @ 2010-03-16 6:41 ` konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 01/10] [ARM] tegra: initial tegra support konkers at google.com 2010-03-18 8:32 ` [RFC/PATCH 00/10] Tegra2 support Russell King - ARM Linux 2010-03-16 8:49 ` [RFC/PATCH] ARM: add Tegra support Mike Rapoport 1 sibling, 2 replies; 37+ messages in thread From: konkers at google.com @ 2010-03-16 6:41 UTC (permalink / raw) To: linux-arm-kernel Here's the cleaned up patch stack as promised. We've incorporated the feedback from Gary and Russel. I've pushed these patches to the linux-tegra-2.6.34-rc1 branch at git://android.git.kernel.org/kernel/tegra.git Cheers, Erik ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 01/10] [ARM] tegra: initial tegra support 2010-03-16 6:41 ` [RFC/PATCH 00/10] Tegra2 support konkers at google.com @ 2010-03-16 6:41 ` konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 02/10] [ARM] tegra: Add IRQ support konkers at google.com 2010-03-17 7:57 ` [RFC/PATCH 01/10] [ARM] tegra: initial tegra support Mike Rapoport 2010-03-18 8:32 ` [RFC/PATCH 00/10] Tegra2 support Russell King - ARM Linux 1 sibling, 2 replies; 37+ messages in thread From: konkers at google.com @ 2010-03-16 6:41 UTC (permalink / raw) To: linux-arm-kernel From: Erik Gilling <konkers@android.com> Signed-off-by: Colin Cross <ccross@android.com> Signed-off-by: Erik Gilling <konkers@android.com> --- arch/arm/Kconfig | 13 ++ arch/arm/Makefile | 1 + arch/arm/mach-tegra/Kconfig | 53 ++++++ arch/arm/mach-tegra/Makefile | 2 + arch/arm/mach-tegra/Makefile.boot | 7 + arch/arm/mach-tegra/board.h | 32 ++++ arch/arm/mach-tegra/common.c | 44 +++++ arch/arm/mach-tegra/include/mach/barriers.h | 30 ++++ arch/arm/mach-tegra/include/mach/debug-macro.S | 45 +++++ arch/arm/mach-tegra/include/mach/dma.h | 24 +++ arch/arm/mach-tegra/include/mach/entry-macro.S | 118 ++++++++++++++ arch/arm/mach-tegra/include/mach/hardware.h | 24 +++ arch/arm/mach-tegra/include/mach/io.h | 79 +++++++++ arch/arm/mach-tegra/include/mach/iomap.h | 204 ++++++++++++++++++++++++ arch/arm/mach-tegra/include/mach/memory.h | 28 ++++ arch/arm/mach-tegra/include/mach/nand.h | 54 +++++++ arch/arm/mach-tegra/include/mach/system.h | 39 +++++ arch/arm/mach-tegra/include/mach/timex.h | 26 +++ arch/arm/mach-tegra/include/mach/uncompress.h | 78 +++++++++ arch/arm/mach-tegra/include/mach/vmalloc.h | 28 ++++ arch/arm/mach-tegra/io.c | 78 +++++++++ arch/arm/mm/Kconfig | 2 +- 22 files changed, 1008 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-tegra/Kconfig create mode 100644 arch/arm/mach-tegra/Makefile create mode 100644 arch/arm/mach-tegra/Makefile.boot create mode 100644 arch/arm/mach-tegra/board.h create mode 100644 arch/arm/mach-tegra/common.c create mode 100644 arch/arm/mach-tegra/include/mach/barriers.h create mode 100644 arch/arm/mach-tegra/include/mach/debug-macro.S create mode 100644 arch/arm/mach-tegra/include/mach/dma.h create mode 100644 arch/arm/mach-tegra/include/mach/entry-macro.S create mode 100644 arch/arm/mach-tegra/include/mach/hardware.h create mode 100644 arch/arm/mach-tegra/include/mach/io.h create mode 100644 arch/arm/mach-tegra/include/mach/iomap.h create mode 100644 arch/arm/mach-tegra/include/mach/memory.h create mode 100644 arch/arm/mach-tegra/include/mach/nand.h create mode 100644 arch/arm/mach-tegra/include/mach/system.h create mode 100644 arch/arm/mach-tegra/include/mach/timex.h create mode 100644 arch/arm/mach-tegra/include/mach/uncompress.h create mode 100644 arch/arm/mach-tegra/include/mach/vmalloc.h create mode 100644 arch/arm/mach-tegra/io.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3b18128..1232104 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -570,6 +570,17 @@ config ARCH_NUC93X Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a low-power and high performance MPEG-4/JPEG multimedia controller chip. +config ARCH_TEGRA + bool "NVIDIA Tegra" + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + select GENERIC_GPIO + select HAVE_CLK + select ARCH_HAS_BARRIERS if CACHE_L2X0 + help + This enables support for NVIDIA Tegra based systems (Tegra APX, + Tegra 6xx and Tegra 2 series). + config ARCH_PNX4008 bool "Philips Nexperia PNX4008 Mobile" select CPU_ARM926T @@ -852,6 +863,8 @@ if ARCH_S5PC1XX source "arch/arm/mach-s5pc100/Kconfig" endif +source "arch/arm/mach-tegra/Kconfig" + source "arch/arm/mach-u300/Kconfig" source "arch/arm/mach-ux500/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 81f54ca..9f2a5fe 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -167,6 +167,7 @@ machine-$(CONFIG_ARCH_SA1100) := sa1100 machine-$(CONFIG_ARCH_SHARK) := shark machine-$(CONFIG_ARCH_STMP378X) := stmp378x machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx +machine-$(CONFIG_ARCH_TEGRA) := tegra machine-$(CONFIG_ARCH_U300) := u300 machine-$(CONFIG_ARCH_U8500) := ux500 machine-$(CONFIG_ARCH_VERSATILE) := versatile diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig new file mode 100644 index 0000000..64ab14f --- /dev/null +++ b/arch/arm/mach-tegra/Kconfig @@ -0,0 +1,53 @@ +if ARCH_TEGRA + +comment "NVIDIA Tegra options" + +choice + prompt "Select Tegra processor family for target system" + +config ARCH_TEGRA_2x_SOC + bool "Tegra 2 family" + select CPU_V7 + select ARM_GIC + help + Support for NVIDIA Tegra AP20 and T20 processors, based on the + ARM CortexA9MP CPU and the ARM PL310 L2 cache controller + +endchoice + + +choice + prompt "Select Tegra-based product" + +config MACH_HARMONY + bool "Harmony board" + help + Support for nVidia Harmony development platform + +endchoice + +choice + prompt "Low-level debug console UART" + default TEGRA_DEBUG_UART_NONE + +config TEGRA_DEBUG_UART_NONE + bool "None" + +config TEGRA_DEBUG_UARTA + bool "UART-A" + +config TEGRA_DEBUG_UARTB + bool "UART-B" + +config TEGRA_DEBUG_UARTC + bool "UART-C" + +config TEGRA_DEBUG_UARTD + bool "UART-D" + +config TEGRA_DEBUG_UARTE + bool "UART-E" + +endchoice + +endif diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile new file mode 100644 index 0000000..81f003d --- /dev/null +++ b/arch/arm/mach-tegra/Makefile @@ -0,0 +1,2 @@ +obj-y += common.o +obj-y += io.o diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot new file mode 100644 index 0000000..e30ea7c --- /dev/null +++ b/arch/arm/mach-tegra/Makefile.boot @@ -0,0 +1,7 @@ +zreladdr-$(CONFIG_ARCH_TEGRA_1x_SOC) := 0x00008000 +params_phys-$(CONFIG_ARCH_TEGRA_1x_SOC) := 0x00000100 +initrd_phys-$(CONFIG_ARCH_TEGRA_1x_SOC) := 0x00800000 + +zreladdr-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00008000 +params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00000100 +initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000 diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h new file mode 100644 index 0000000..3d06354 --- /dev/null +++ b/arch/arm/mach-tegra/board.h @@ -0,0 +1,32 @@ +/* + * arch/arm/mach-tegra/board.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * Erik Gilling <konkers@google.com> + * + * 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. + * + */ + +#ifndef __MACH_TEGRA_BOARD_H +#define __MACH_TEGRA_BOARD_H + +#include <linux/types.h> + +void __init tegra_common_init(void); +void __init tegra_map_common_io(void); +void __init tegra_init_irq(void); +void __init tegra_init_clock(void); + +extern struct sys_timer tegra_timer; +#endif diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c new file mode 100644 index 0000000..20875ee --- /dev/null +++ b/arch/arm/mach-tegra/common.c @@ -0,0 +1,44 @@ +/* + * arch/arm/mach-tegra/board-harmony.c + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@android.com> + * + * 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. + * + */ + +#include <linux/init.h> +#include <linux/io.h> + +#include <asm/hardware/cache-l2x0.h> + +#include <mach/iomap.h> + +#include "board.h" + +void __init tegra_init_cache(void) +{ +#ifdef CONFIG_CACHE_L2X0 + void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000; + + writel(0x331, p + L2X0_TAG_LATENCY_CTRL); + writel(0x441, p + L2X0_DATA_LATENCY_CTRL); + + l2x0_init(p, 0x6C080001, 0x8200c3fe); +#endif +} + +void __init tegra_common_init(void) +{ + tegra_init_cache(); +} diff --git a/arch/arm/mach-tegra/include/mach/barriers.h b/arch/arm/mach-tegra/include/mach/barriers.h new file mode 100644 index 0000000..cc11517 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/barriers.h @@ -0,0 +1,30 @@ +/* + * arch/arm/mach-realview/include/mach/barriers.h + * + * Copyright (C) 2010 ARM Ltd. + * Written by Catalin Marinas <catalin.marinas@arm.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. + * + * 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 __MACH_BARRIERS_H +#define __MACH_BARRIERS_H + +#include <asm/outercache.h> + +#define rmb() dmb() +#define wmb() do { dsb(); outer_sync(); } while (0) +#define mb() wmb() + +#endif /* __MACH_BARRIERS_H */ diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S new file mode 100644 index 0000000..a4f0b80 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/debug-macro.S @@ -0,0 +1,45 @@ +/* + * arch/arm/mach-tegra/include/mach/debug-macro.S + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * Erik Gilling <konkers@google.com> + * + * 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. + * + */ + +#include <mach/io.h> + + .macro addruart,rx, tmp + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + ldreq \rx, =IO_APB_PHYS @ physical + ldrne \rx, =IO_APB_VIRT @ virtual +#if defined(CONFIG_TEGRA_DEBUG_UART_NONE) +#error "A debug UART must be selected in the kernel config to use DEBUG_LL" +#elif defined(CONFIG_TEGRA_DEBUG_UARTA) + orr \rx, \rx, #0x6000 +#elif defined(CONFIG_TEGRA_DEBUG_UARTB) + orr \rx, \rx, #0x6040 +#elif defined(CONFIG_TEGRA_DEBUG_UARTC) + orr \rx, \rx, #0x6200 +#elif defined(CONFIG_TEGRA_DEBUG_UARTD) + orr \rx, \rx, #0x6300 +#elif defined(CONFIG_TEGRA_DEBUG_UARTE) + orr \rx, \rx, #0x6400 +#endif + .endm + +#define UART_SHIFT 2 +#include <asm/hardware/debug-8250.S> + diff --git a/arch/arm/mach-tegra/include/mach/dma.h b/arch/arm/mach-tegra/include/mach/dma.h new file mode 100644 index 0000000..b286386 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/dma.h @@ -0,0 +1,24 @@ +/* + * arch/arm/mach-tegra/include/mach/dma.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * Erik Gilling <konkers@google.com> + * + * 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. + * + */ + +#ifndef __MACH_TEGRA_DMA_H +#define __MACH_TEGRA_DMA_H + +#endif diff --git a/arch/arm/mach-tegra/include/mach/entry-macro.S b/arch/arm/mach-tegra/include/mach/entry-macro.S new file mode 100644 index 0000000..2ba9e5c --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/entry-macro.S @@ -0,0 +1,118 @@ +/* arch/arm/mach-tegra/include/mach/entry-macro.S + * + * Copyright (C) 2009 Palm, Inc. + * + * 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. + * + */ +#include <mach/iomap.h> +#include <mach/io.h> + +#if defined(CONFIG_ARM_GIC) + +#include <asm/hardware/gic.h> + + /* Uses the GIC interrupt controller built into the cpu */ +#define ICTRL_BASE (IO_CPU_VIRT + 0x100) + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + movw \base, #(ICTRL_BASE & 0x0000ffff) + movt \base, #((ICTRL_BASE & 0xffff0000) >> 16) + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + /* + * The interrupt numbering scheme is defined in the + * interrupt controller spec. To wit: + * + * Interrupts 0-15 are IPI + * 16-28 are reserved + * 29-31 are local. We allow 30 to be used for the watchdog. + * 32-1020 are global + * 1021-1022 are reserved + * 1023 is "spurious" (no interrupt) + * + * For now, we ignore all local interrupts so only return an interrupt + * if it's between 30 and 1020. The test_for_ipi routine below will + * pick up on IPIs. + * + * A simple read from the controller will tell us the number of the + * highest priority enabled interrupt. We then just need to check + * whether it is in the valid range for an IRQ (30-1020 inclusive). + */ + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + /* bits 12-10 = src CPU, 9-0 = int # */ + ldr \irqstat, [\base, #GIC_CPU_INTACK] + + ldr \tmp, =1021 + + bic \irqnr, \irqstat, #0x1c00 + + cmp \irqnr, #29 + cmpcc \irqnr, \irqnr + cmpne \irqnr, \tmp + cmpcs \irqnr, \irqnr + + .endm + + /* We assume that irqstat (the raw value of the IRQ acknowledge + * register) is preserved from the macro above. + * If there is an IPI, we immediately signal end of interrupt on the + * controller, since this requires the original irqstat value which + * we won't easily be able to recreate later. + */ + + .macro test_for_ipi, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + cmp \irqnr, #16 + strcc \irqstat, [\base, #GIC_CPU_EOI] + cmpcs \irqnr, \irqnr + .endm + + /* As above, this assumes that irqstat and base are preserved.. */ + + .macro test_for_ltirq, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + mov \tmp, #0 + cmp \irqnr, #29 + moveq \tmp, #1 + streq \irqstat, [\base, #GIC_CPU_EOI] + cmp \tmp, #0 + .endm + +#else + /* legacy interrupt controller for AP16 */ + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + @ enable imprecise aborts + cpsie a + @ EVP base at 0xf010f000 + mov \base, #0xf0000000 + orr \base, #0x00100000 + orr \base, #0x0000f000 + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \irqnr, [\base, #0x20] @ EVT_IRQ_STS + cmp \irqnr, #0x80 + .endm +#endif diff --git a/arch/arm/mach-tegra/include/mach/hardware.h b/arch/arm/mach-tegra/include/mach/hardware.h new file mode 100644 index 0000000..6014edf --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/hardware.h @@ -0,0 +1,24 @@ +/* + * arch/arm/mach-tegra/include/mach/hardware.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * Erik Gilling <konkers@google.com> + * + * 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. + * + */ + +#ifndef __MACH_TEGRA_HARDWARE_H +#define __MACH_TEGRA_HARDWARE_H + +#endif diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h new file mode 100644 index 0000000..35edfc3 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/io.h @@ -0,0 +1,79 @@ +/* + * arch/arm/mach-tegra/include/mach/io.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * Erik Gilling <konkers@google.com> + * + * 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. + * + */ + +#ifndef __MACH_TEGRA_IO_H +#define __MACH_TEGRA_IO_H + +#define IO_SPACE_LIMIT 0xffffffff + +/* On TEGRA, many peripherals are very closely packed in + * two 256MB io windows (that actually only use about 64KB + * at the start of each). + * + * We will just map the first 1MB of each window (to minimize + * pt entries needed) and provide a macro to transform physical + * io addresses to an appropriate void __iomem *. + * + */ + +#define IO_CPU_PHYS 0x50040000 +#define IO_CPU_VIRT 0xFE000000 +#define IO_CPU_SIZE SZ_16K + +#define IO_PPSB_PHYS 0x60000000 +#define IO_PPSB_VIRT 0xFE200000 +#define IO_PPSB_SIZE SZ_1M + +#define IO_APB_PHYS 0x70000000 +#define IO_APB_VIRT 0xFE300000 +#define IO_APB_SIZE SZ_1M + +#define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz))) +#define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst))) + +#define IO_TO_VIRT(n) ( \ + IO_TO_VIRT_BETWEEN((n), IO_PPSB_PHYS, IO_PPSB_SIZE) ? \ + IO_TO_VIRT_XLATE((n), IO_PPSB_PHYS, IO_PPSB_VIRT) : \ + IO_TO_VIRT_BETWEEN((n), IO_APB_PHYS, IO_APB_SIZE) ? \ + IO_TO_VIRT_XLATE((n), IO_APB_PHYS, IO_APB_VIRT) : \ + IO_TO_VIRT_BETWEEN((n), IO_CPU_PHYS, IO_CPU_SIZE) ? \ + IO_TO_VIRT_XLATE((n), IO_CPU_PHYS, IO_CPU_VIRT) : \ + 0) + +#ifndef __ASSEMBLER__ + +#define __arch_ioremap(p, s, t) tegra_ioremap(p, s, t) +#define __arch_iounmap(v) tegra_iounmap(v) + +void __iomem *tegra_ioremap(unsigned long phys, size_t size, unsigned int type); +void tegra_iounmap(volatile void __iomem *addr); + +#define IO_ADDRESS(n) ((void __iomem *) IO_TO_VIRT(n)) + +static inline void __iomem *__io(unsigned long addr) +{ + return (void __iomem *)addr; +} +#define __io(a) __io(a) +#define __mem_pci(a) (a) + +#endif + +#endif diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h new file mode 100644 index 0000000..4814c73 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/iomap.h @@ -0,0 +1,204 @@ +/* + * arch/arm/mach-tegra/include/mach/iomap.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * Erik Gilling <konkers@google.com> + * + * 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. + * + */ + +#ifndef __MACH_TEGRA_IOMAP_H +#define __MACH_TEGRA_IOMAP_H + +#include <mach/io.h> +#include <asm/sizes.h> + +#define TEGRA_ARM_PERIF_BASE 0x50040000 +#define TEGRA_ARM_PERIF_SIZE SZ_8K + +#define TEGRA_ARM_INT_DIST_BASE 0x50041000 +#define TEGRA_ARM_INT_DIST_SIZE SZ_4K + +#define TEGRA_DISPLAY_BASE 0x54200000 +#define TEGRA_DISPLAY_SIZE SZ_256K + +#define TEGRA_DISPLAY2_BASE 0x54240000 +#define TEGRA_DISPLAY2_SIZE SZ_256K + +#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000 +#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64 + +#define TEGRA_SECONDARY_ICTLR_BASE 0x60004100 +#define TEGRA_SECONDARY_ICTLR_SIZE SZ_64 + +#define TEGRA_TERTIARY_ICTLR_BASE 0x60004200 +#define TEGRA_TERTIARY_ICTLR_SIZE SZ_64 + +#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300 +#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64 + +#define TEGRA_TMR1_BASE 0x60005000 +#define TEGRA_TMR1_SIZE SZ_8 + +#define TEGRA_TMR2_BASE 0x60005008 +#define TEGRA_TMR2_SIZE SZ_8 + +#define TEGRA_TMRUS_BASE 0x60005010 +#define TEGRA_TMRUS_SIZE SZ_64 + +#define TEGRA_TMR3_BASE 0x60005050 +#define TEGRA_TMR3_SIZE SZ_8 + +#define TEGRA_TMR4_BASE 0x60005058 +#define TEGRA_TMR4_SIZE SZ_8 + +#define TEGRA_CLK_RESET_BASE 0x60006000 +#define TEGRA_CLK_RESET_SIZE SZ_4K + +#define TEGRA_FLOW_CTRL_BASE 0x60007000 +#define TEGRA_FLOW_CTRL_SIZE 20 + +#define TEGRA_STATMON_BASE 0x6000C4000 +#define TEGRA_STATMON_SIZE SZ_1K + +#define TEGRA_GPIO_BASE 0x6000D000 +#define TEGRA_GPIO_SIZE SZ_4K + +#define TEGRA_EXCEPTION_VECTORS_BASE 0x6000F000 +#define TEGRA_EXCEPTION_VECTORS_SIZE SZ_4K + +#define TEGRA_APB_MISC_BASE 0x70000000 +#define TEGRA_APB_MISC_SIZE SZ_4K + +#define TEGRA_AC97_BASE 0x70002000 +#define TEGRA_AC97_SIZE SZ_512 + +#define TEGRA_SPDIF_BASE 0x70002400 +#define TEGRA_SPDIF_SIZE SZ_512 + +#define TEGRA_I2S1_BASE 0x70002800 +#define TEGRA_I2S1_SIZE SZ_256 + +#define TEGRA_I2S2_BASE 0x70002A00 +#define TEGRA_I2S2_SIZE SZ_256 + +#define TEGRA_UARTA_BASE 0x70006000 +#define TEGRA_UARTA_SIZE SZ_64 + +#define TEGRA_UARTB_BASE 0x70006040 +#define TEGRA_UARTB_SIZE SZ_64 + +#define TEGRA_UARTC_BASE 0x70006200 +#define TEGRA_UARTC_SIZE SZ_256 + +#define TEGRA_UARTD_BASE 0x70006300 +#define TEGRA_UARTD_SIZE SZ_256 + +#define TEGRA_UARTE_BASE 0x70006400 +#define TEGRA_UARTE_SIZE SZ_256 + +#define TEGRA_NAND_BASE 0x70008000 +#define TEGRA_NAND_SIZE SZ_256 + +#define TEGRA_HSMMC_BASE 0x70008500 +#define TEGRA_HSMMC_SIZE SZ_256 + +#define TEGRA_SNOR_BASE 0x70009000 +#define TEGRA_SNOR_SIZE SZ_4K + +#define TEGRA_PWFM_BASE 0x7000A000 +#define TEGRA_PWFM_SIZE SZ_256 + +#define TEGRA_MIPI_BASE 0x7000B000 +#define TEGRA_MIPI_SIZE SZ_256 + +#define TEGRA_I2C_BASE 0x7000C000 +#define TEGRA_I2C_SIZE SZ_256 + +#define TEGRA_TWC_BASE 0x7000C100 +#define TEGRA_TWC_SIZE SZ_256 + +#define TEGRA_SPI_BASE 0x7000C380 +#define TEGRA_SPI_SIZE 48 + +#define TEGRA_I2C2_BASE 0x7000C400 +#define TEGRA_I2C2_SIZE SZ_256 + +#define TEGRA_I2C3_BASE 0x7000C500 +#define TEGRA_I2C3_SIZE SZ_256 + +#define TEGRA_OWR_BASE 0x7000D000 +#define TEGRA_OWR_SIZE 80 + +#define TEGRA_DVC_BASE 0x7000D000 +#define TEGRA_DVC_SIZE SZ_512 + +#define TEGRA_SPI1_BASE 0x7000D400 +#define TEGRA_SPI1_SIZE SZ_512 + +#define TEGRA_SPI2_BASE 0x7000D600 +#define TEGRA_SPI2_SIZE SZ_512 + +#define TEGRA_SPI3_BASE 0x7000D800 +#define TEGRA_SPI3_SIZE SZ_512 + +#define TEGRA_SPI4_BASE 0x7000DA00 +#define TEGRA_SPI4_SIZE SZ_512 + +#define TEGRA_RTC_BASE 0x7000E000 +#define TEGRA_RTC_SIZE SZ_256 + +#define TEGRA_KBC_BASE 0x7000E200 +#define TEGRA_KBC_SIZE SZ_256 + +#define TEGRA_PMC_BASE 0x7000E400 +#define TEGRA_PMC_SIZE SZ_256 + +#define TEGRA_MC_BASE 0x7000F000 +#define TEGRA_MC_SIZE SZ_1K + +#define TEGRA_EMC_BASE 0x7000F400 +#define TEGRA_EMC_SIZE SZ_1K + +#define TEGRA_FUSE_BASE 0x7000F800 +#define TEGRA_FUSE_SIZE SZ_1K + +#define TEGRA_KFUSE_BASE 0x7000FC00 +#define TEGRA_KFUSE_SIZE SZ_1K + +#define TEGRA_CSITE_BASE 0x70040000 +#define TEGRA_CSITE_SIZE SZ_256K + +#define TEGRA_USB_BASE 0xC5000000 +#define TEGRA_USB_SIZE SZ_16K + +#define TEGRA_USB1_BASE 0xC5004000 +#define TEGRA_USB1_SIZE SZ_16K + +#define TEGRA_USB2_BASE 0xC5008000 +#define TEGRA_USB2_SIZE SZ_16K + +#define TEGRA_SDMMC1_BASE 0xC8000000 +#define TEGRA_SDMMC1_SIZE SZ_512 + +#define TEGRA_SDMMC2_BASE 0xC8000200 +#define TEGRA_SDMMC2_SIZE SZ_512 + +#define TEGRA_SDMMC3_BASE 0xC8000400 +#define TEGRA_SDMMC3_SIZE SZ_512 + +#define TEGRA_SDMMC4_BASE 0xC8000600 +#define TEGRA_SDMMC4_SIZE SZ_512 + +#endif diff --git a/arch/arm/mach-tegra/include/mach/memory.h b/arch/arm/mach-tegra/include/mach/memory.h new file mode 100644 index 0000000..6151bab --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/memory.h @@ -0,0 +1,28 @@ +/* + * arch/arm/mach-tegra/include/mach/memory.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * Erik Gilling <konkers@google.com> + * + * 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. + * + */ + +#ifndef __MACH_TEGRA_MEMORY_H +#define __MACH_TEGRA_MEMORY_H + +/* physical offset of RAM */ +#define PHYS_OFFSET UL(0) + +#endif + diff --git a/arch/arm/mach-tegra/include/mach/nand.h b/arch/arm/mach-tegra/include/mach/nand.h new file mode 100644 index 0000000..2d26fec --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/nand.h @@ -0,0 +1,54 @@ +/* + * arch/arm/mach-tegra/include/mach/nand.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * Dima Zavin <dmitriyz@google.com> + * + * 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. + * + */ + +#ifndef __MACH_TEGRA_NAND_H +#define __MACH_TEGRA_NAND_H + +struct tegra_nand_chip_parms { + uint8_t vendor_id; + uint8_t device_id; + uint32_t flags; + + uint32_t capacity; + + /* all timing info is in nanoseconds */ + struct { + uint32_t trp; + uint32_t trh; + uint32_t twp; + uint32_t twh; + uint32_t tcs; + uint32_t twhr; + uint32_t tcr_tar_trr; + uint32_t twb; + uint32_t trp_resp; + uint32_t tadl; + } timing; +}; + +struct tegra_nand_platform { + uint8_t max_chips; + struct tegra_nand_chip_parms *chip_parms; + unsigned int nr_chip_parms; + struct mtd_partition *parts; + unsigned int nr_parts; +}; + +#endif diff --git a/arch/arm/mach-tegra/include/mach/system.h b/arch/arm/mach-tegra/include/mach/system.h new file mode 100644 index 0000000..84d5d46 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/system.h @@ -0,0 +1,39 @@ +/* + * arch/arm/mach-tegra/include/mach/system.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * Erik Gilling <konkers@google.com> + * + * 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. + * + */ + +#ifndef __MACH_TEGRA_SYSTEM_H +#define __MACH_TEGRA_SYSTEM_H + +#include <mach/hardware.h> +#include <mach/iomap.h> + +static inline void arch_idle(void) +{ +} + +static inline void arch_reset(char mode, const char *cmd) +{ + void __iomem *reset = IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x04); + u32 reg = readl(reset); + reg |= 0x04; + writel(reg, reset); +} + +#endif diff --git a/arch/arm/mach-tegra/include/mach/timex.h b/arch/arm/mach-tegra/include/mach/timex.h new file mode 100644 index 0000000..a44ccbd --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/timex.h @@ -0,0 +1,26 @@ +/* + * arch/arm/mach-tegra/include/mach/timex.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * Erik Gilling <konkers@google.com> + * + * 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. + * + */ + +#ifndef __MACH_TEGRA_TIMEX_H +#define __MACH_TEGRA_TIMEX_H + +#define CLOCK_TICK_RATE 1000000 + +#endif diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h new file mode 100644 index 0000000..6c4dd81 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/uncompress.h @@ -0,0 +1,78 @@ +/* + * arch/arm/mach-tegra/include/mach/uncompress.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * Erik Gilling <konkers@google.com> + * + * 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. + * + */ + +#ifndef __MACH_TEGRA_UNCOMPRESS_H +#define __MACH_TEGRA_UNCOMPRESS_H + +#include <linux/types.h> +#include <linux/serial_reg.h> + +#include <mach/iomap.h> + +#if defined(CONFIG_TEGRA_DEBUG_UARTA) +#define DEBUG_UART_BASE TEGRA_UARTA_BASE +#elif defined(CONFIG_TEGRA_DEBUG_UARTB) +#define DEBUG_UART_BASE TEGRA_UARTB_BASE +#elif defined(CONFIG_TEGRA_DEBUG_UARTC) +#define DEBUG_UART_BASE TEGRA_UARTC_BASE +#elif defined(CONFIG_TEGRA_DEBUG_UARTD) +#define DEBUG_UART_BASE TEGRA_UARTD_BASE +#elif defined(CONFIG_TEGRA_DEBUG_UARTE) +#define DEBUG_UART_BASE TEGRA_UARTE_BASE +#else +#define DEBUG_UART_BASE NULL +#endif + +static void putc(int c) +{ + volatile u8 *uart = (volatile u8 *)DEBUG_UART_BASE; + int shift = 2; + + if (uart == NULL) + return; + + while (!(uart[UART_LSR << shift] & UART_LSR_THRE)) + barrier(); + uart[UART_TX << shift] = c; +} + +static inline void flush(void) +{ +} + +static inline void arch_decomp_setup(void) +{ + volatile u8 *uart = (volatile u8 *)DEBUG_UART_BASE; + int shift = 2; + + if (uart == NULL) + return; + + uart[UART_LCR << shift] |= UART_LCR_DLAB; + uart[UART_DLL << shift] = 0x75; + uart[UART_DLM << shift] = 0x0; + uart[UART_LCR << shift] = 3; +} + +static inline void arch_decomp_wdog(void) +{ +} + +#endif diff --git a/arch/arm/mach-tegra/include/mach/vmalloc.h b/arch/arm/mach-tegra/include/mach/vmalloc.h new file mode 100644 index 0000000..267a141 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/vmalloc.h @@ -0,0 +1,28 @@ +/* + * arch/arm/mach-tegra/include/mach/vmalloc.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * Erik Gilling <konkers@google.com> + * + * 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. + * + */ + +#ifndef __MACH_TEGRA_VMALLOC_H +#define __MACH_TEGRA_VMALLOC_H + +#include <asm/sizes.h> + +#define VMALLOC_END 0xFE000000 + +#endif diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c new file mode 100644 index 0000000..34f88db --- /dev/null +++ b/arch/arm/mach-tegra/io.c @@ -0,0 +1,78 @@ +/* + * arch/arm/mach-tegra/io.c + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * Erik Gilling <konkers@google.com> + * + * 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. + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/mm.h> + +#include <mach/hardware.h> +#include <asm/io.h> +#include <asm/page.h> +#include <asm/mach/map.h> + +#include "board.h" + +static struct map_desc tegra_io_desc[] __initdata = { + { + .virtual = IO_PPSB_VIRT, + .pfn = __phys_to_pfn(IO_PPSB_PHYS), + .length = IO_PPSB_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = IO_APB_VIRT, + .pfn = __phys_to_pfn(IO_APB_PHYS), + .length = IO_APB_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = IO_CPU_VIRT, + .pfn = __phys_to_pfn(IO_CPU_PHYS), + .length = IO_CPU_SIZE, + .type = MT_DEVICE, + }, +}; + +void __init tegra_map_common_io(void) +{ + iotable_init(tegra_io_desc, ARRAY_SIZE(tegra_io_desc)); +} + +/* + * Intercept ioremap() requests for addresses in our fixed mapping regions. + */ +void __iomem *tegra_ioremap(unsigned long p, size_t size, unsigned int type) +{ + void __iomem *v = IO_ADDRESS(p); + if (v == NULL) + v = __arm_ioremap(p, size, type); + return v; +} +EXPORT_SYMBOL(tegra_ioremap); + +void tegra_iounmap(volatile void __iomem *addr) +{ + unsigned long virt = (unsigned long)addr; + + if (virt >= VMALLOC_START && virt < VMALLOC_END) + __iounmap(addr); +} +EXPORT_SYMBOL(tegra_iounmap); diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index c4ed9f9..84b5be3 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -754,7 +754,7 @@ config CACHE_FEROCEON_L2_WRITETHROUGH config CACHE_L2X0 bool "Enable the L2x0 outer cache controller" depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ - REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4 + REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4 || ARCH_TEGRA default y select OUTER_CACHE help -- 1.6.5.6 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [RFC/PATCH 02/10] [ARM] tegra: Add IRQ support 2010-03-16 6:41 ` [RFC/PATCH 01/10] [ARM] tegra: initial tegra support konkers at google.com @ 2010-03-16 6:41 ` konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 03/10] [ARM] tegra: Add clock support konkers at google.com 2010-03-17 7:57 ` [RFC/PATCH 01/10] [ARM] tegra: initial tegra support Mike Rapoport 1 sibling, 1 reply; 37+ messages in thread From: konkers at google.com @ 2010-03-16 6:41 UTC (permalink / raw) To: linux-arm-kernel From: Erik Gilling <konkers@android.com> Signed-off-by: Colin Cross <ccross@android.com> Signed-off-by: Erik Gilling <konkers@android.com> --- arch/arm/mach-tegra/Makefile | 1 + arch/arm/mach-tegra/include/mach/irqs.h | 173 +++++++++++++++++++++++++++++++ arch/arm/mach-tegra/irq.c | 34 ++++++ 3 files changed, 208 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-tegra/include/mach/irqs.h create mode 100644 arch/arm/mach-tegra/irq.c diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 81f003d..a0d2c5b 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -1,2 +1,3 @@ obj-y += common.o obj-y += io.o +obj-y += irq.o diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h new file mode 100644 index 0000000..78e1a48 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/irqs.h @@ -0,0 +1,173 @@ +/* + * arch/arm/mach-tegra/include/mach/irqs.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * Erik Gilling <konkers@google.com> + * + * 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. + * + */ + +#ifndef __MACH_TEGRA_IRQS_H +#define __MACH_TEGRA_IRQS_H + +#define INT_GIC_BASE 0 + +#define IRQ_LOCALTIMER 29 + +/* Primary Interrupt Controller */ +#define INT_PRI_BASE (INT_GIC_BASE + 32) +#define INT_TMR1 (INT_PRI_BASE + 0) +#define INT_TMR2 (INT_PRI_BASE + 1) +#define INT_RTC (INT_PRI_BASE + 2) +#define INT_I2S2 (INT_PRI_BASE + 3) +#define INT_SHR_SEM_INBOX_IBF (INT_PRI_BASE + 4) +#define INT_SHR_SEM_INBOX_IBE (INT_PRI_BASE + 5) +#define INT_SHR_SEM_OUTBOX_IBF (INT_PRI_BASE + 6) +#define INT_SHR_SEM_OUTBOX_IBE (INT_PRI_BASE + 7) +#define INT_VDE_UCQ_ERROR (INT_PRI_BASE + 8) +#define INT_VDE_SYNC_TOKEN (INT_PRI_BASE + 9) +#define INT_VDE_BSE_V (INT_PRI_BASE + 10) +#define INT_VDE_BSE_A (INT_PRI_BASE + 11) +#define INT_VDE_SXE (INT_PRI_BASE + 12) +#define INT_I2S1 (INT_PRI_BASE + 13) +#define INT_SDMMC1 (INT_PRI_BASE + 14) +#define INT_SDMMC2 (INT_PRI_BASE + 15) +#define INT_XIO (INT_PRI_BASE + 16) +#define INT_VDE (INT_PRI_BASE + 17) +#define INT_AVP_UCQ (INT_PRI_BASE + 18) +#define INT_SDMMC3 (INT_PRI_BASE + 19) +#define INT_USB (INT_PRI_BASE + 20) +#define INT_USB2 (INT_PRI_BASE + 21) +#define INT_PRI_RES_22 (INT_PRI_BASE + 22) +#define INT_EIDE (INT_PRI_BASE + 23) +#define INT_NANDFLASH (INT_PRI_BASE + 24) +#define INT_VCP (INT_PRI_BASE + 25) +#define INT_APB_DMA (INT_PRI_BASE + 26) +#define INT_AHB_DMA (INT_PRI_BASE + 27) +#define INT_GNT_0 (INT_PRI_BASE + 28) +#define INT_GNT_1 (INT_PRI_BASE + 29) +#define INT_OWR (INT_PRI_BASE + 30) +#define INT_SDMMC4 (INT_PRI_BASE + 31) + +/* Secondary Interrupt Controller */ +#define INT_SEC_BASE (INT_PRI_BASE + 32) +#define INT_GPIO1 (INT_SEC_BASE + 0) +#define INT_GPIO2 (INT_SEC_BASE + 1) +#define INT_GPIO3 (INT_SEC_BASE + 2) +#define INT_GPIO4 (INT_SEC_BASE + 3) +#define INT_UARTA (INT_SEC_BASE + 4) +#define INT_UARTB (INT_SEC_BASE + 5) +#define INT_I2C (INT_SEC_BASE + 6) +#define INT_SPI (INT_SEC_BASE + 7) +#define INT_TWC (INT_SEC_BASE + 8) +#define INT_TMR3 (INT_SEC_BASE + 9) +#define INT_TMR4 (INT_SEC_BASE + 10) +#define INT_FLOW_RSM0 (INT_SEC_BASE + 11) +#define INT_FLOW_RSM1 (INT_SEC_BASE + 12) +#define INT_SPDIF (INT_SEC_BASE + 13) +#define INT_UARTC (INT_SEC_BASE + 14) +#define INT_MIPI (INT_SEC_BASE + 15) +#define INT_EVENTA (INT_SEC_BASE + 16) +#define INT_EVENTB (INT_SEC_BASE + 17) +#define INT_EVENTC (INT_SEC_BASE + 18) +#define INT_EVENTD (INT_SEC_BASE + 19) +#define INT_VFIR (INT_SEC_BASE + 20) +#define INT_DVC (INT_SEC_BASE + 21) +#define INT_SYS_STATS_MON (INT_SEC_BASE + 22) +#define INT_GPIO5 (INT_SEC_BASE + 23) +#define INT_CPU0_PMU_INTR (INT_SEC_BASE + 24) +#define INT_CPU2_PMU_INTR (INT_SEC_BASE + 25) +#define INT_SEC_RES_26 (INT_SEC_BASE + 26) +#define INT_S_LINK1 (INT_SEC_BASE + 27) +#define INT_APB_DMA_COP (INT_SEC_BASE + 28) +#define INT_AHB_DMA_COP (INT_SEC_BASE + 29) +#define INT_DMA_TX (INT_SEC_BASE + 30) +#define INT_DMA_RX (INT_SEC_BASE + 31) + +/* Tertiary Interrupt Controller */ +#define INT_TRI_BASE (INT_SEC_BASE + 32) +#define INT_HOST1X_COP_SYNCPT (INT_TRI_BASE + 0) +#define INT_HOST1X_MPCORE_SYNCPT (INT_TRI_BASE + 1) +#define INT_HOST1X_COP_GENERAL (INT_TRI_BASE + 2) +#define INT_HOST1X_MPCORE_GENERAL (INT_TRI_BASE + 3) +#define INT_MPE_GENERAL (INT_TRI_BASE + 4) +#define INT_VI_GENERAL (INT_TRI_BASE + 5) +#define INT_EPP_GENERAL (INT_TRI_BASE + 6) +#define INT_ISP_GENERAL (INT_TRI_BASE + 7) +#define INT_2D_GENERAL (INT_TRI_BASE + 8) +#define INT_DISPLAY_GENERAL (INT_TRI_BASE + 9) +#define INT_DISPLAY_B_GENERAL (INT_TRI_BASE + 10) +#define INT_HDMI (INT_TRI_BASE + 11) +#define INT_TVO_GENERAL (INT_TRI_BASE + 12) +#define INT_MC_GENERAL (INT_TRI_BASE + 13) +#define INT_EMC_GENERAL (INT_TRI_BASE + 14) +#define INT_TRI_RES_15 (INT_TRI_BASE + 15) +#define INT_TRI_RES_16 (INT_TRI_BASE + 16) +#define INT_AC97 (INT_TRI_BASE + 17) +#define INT_SPI_2 (INT_TRI_BASE + 18) +#define INT_SPI_3 (INT_TRI_BASE + 19) +#define INT_I2C2 (INT_TRI_BASE + 20) +#define INT_KBC (INT_TRI_BASE + 21) +#define INT_EXTERNAL_PMU (INT_TRI_BASE + 22) +#define INT_GPIO6 (INT_TRI_BASE + 23) +#define INT_TVDAC (INT_TRI_BASE + 24) +#define INT_GPIO7 (INT_TRI_BASE + 25) +#define INT_UARTD (INT_TRI_BASE + 26) +#define INT_UARTE (INT_TRI_BASE + 27) +#define INT_I2C3 (INT_TRI_BASE + 28) +#define INT_SPI4 (INT_TRI_BASE + 29) +#define INT_TRI_RES_30 (INT_TRI_BASE + 30) +#define INT_SW_RESERVED (INT_TRI_BASE + 31) + +/* Quaternary Interrupt Controller */ +#define INT_QUAD_BASE (INT_TRI_BASE + 32) +#define INT_SNOR (INT_QUAD_BASE + 0) +#define INT_USB3 (INT_QUAD_BASE + 1) +#define INT_PCIE_INTR (INT_QUAD_BASE + 2) +#define INT_PCIE_MSI (INT_QUAD_BASE + 3) +#define INT_QUAD_RES_4 (INT_QUAD_BASE + 4) +#define INT_QUAD_RES_5 (INT_QUAD_BASE + 5) +#define INT_QUAD_RES_6 (INT_QUAD_BASE + 6) +#define INT_QUAD_RES_7 (INT_QUAD_BASE + 7) +#define INT_APB_DMA_CH0 (INT_QUAD_BASE + 8) +#define INT_APB_DMA_CH1 (INT_QUAD_BASE + 9) +#define INT_APB_DMA_CH2 (INT_QUAD_BASE + 10) +#define INT_APB_DMA_CH3 (INT_QUAD_BASE + 11) +#define INT_APB_DMA_CH4 (INT_QUAD_BASE + 12) +#define INT_APB_DMA_CH5 (INT_QUAD_BASE + 13) +#define INT_APB_DMA_CH6 (INT_QUAD_BASE + 14) +#define INT_APB_DMA_CH7 (INT_QUAD_BASE + 15) +#define INT_APB_DMA_CH8 (INT_QUAD_BASE + 16) +#define INT_APB_DMA_CH9 (INT_QUAD_BASE + 17) +#define INT_APB_DMA_CH10 (INT_QUAD_BASE + 18) +#define INT_APB_DMA_CH11 (INT_QUAD_BASE + 19) +#define INT_APB_DMA_CH12 (INT_QUAD_BASE + 20) +#define INT_APB_DMA_CH13 (INT_QUAD_BASE + 21) +#define INT_APB_DMA_CH14 (INT_QUAD_BASE + 22) +#define INT_APB_DMA_CH15 (INT_QUAD_BASE + 23) +#define INT_QUAD_RES_24 (INT_QUAD_BASE + 24) +#define INT_QUAD_RES_25 (INT_QUAD_BASE + 25) +#define INT_QUAD_RES_26 (INT_QUAD_BASE + 26) +#define INT_QUAD_RES_27 (INT_QUAD_BASE + 27) +#define INT_QUAD_RES_28 (INT_QUAD_BASE + 28) +#define INT_QUAD_RES_29 (INT_QUAD_BASE + 29) +#define INT_QUAD_RES_30 (INT_QUAD_BASE + 30) +#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31) + +#define INT_GPIO_BASE (INT_QUAD_BASE + 32) +#define INT_GPIO_NR (28 * 8) + +#define NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR) + +#endif diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c new file mode 100644 index 0000000..2e8cdb0 --- /dev/null +++ b/arch/arm/mach-tegra/irq.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * + * 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. + * + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <asm/hardware/gic.h> +#include <asm/io.h> + +#include <mach/io.h> +#include <mach/iomap.h> + +#include "board.h" + +void __init tegra_init_irq(void) +{ + gic_dist_init(0, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), 29); + gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); +} -- 1.6.5.6 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [RFC/PATCH 03/10] [ARM] tegra: Add clock support 2010-03-16 6:41 ` [RFC/PATCH 02/10] [ARM] tegra: Add IRQ support konkers at google.com @ 2010-03-16 6:41 ` konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 04/10] [ARM] tegra: SMP support konkers at google.com 2010-03-18 8:42 ` [RFC/PATCH 03/10] [ARM] tegra: Add clock support Russell King - ARM Linux 0 siblings, 2 replies; 37+ messages in thread From: konkers at google.com @ 2010-03-16 6:41 UTC (permalink / raw) To: linux-arm-kernel From: Colin Cross <ccross@android.com> Signed-off-by: Colin Cross <ccross@android.com> Signed-off-by: Erik Gilling <konkers@android.com> --- arch/arm/Kconfig | 1 + arch/arm/mach-tegra/Makefile | 2 + arch/arm/mach-tegra/clock.c | 191 +++++++ arch/arm/mach-tegra/clock.h | 103 ++++ arch/arm/mach-tegra/common.c | 1 + arch/arm/mach-tegra/include/mach/clkdev.h | 32 ++ arch/arm/mach-tegra/tegra2_clocks.c | 837 +++++++++++++++++++++++++++++ 7 files changed, 1167 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-tegra/clock.c create mode 100644 arch/arm/mach-tegra/clock.h create mode 100644 arch/arm/mach-tegra/include/mach/clkdev.h create mode 100644 arch/arm/mach-tegra/tegra2_clocks.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1232104..a5be2d6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -576,6 +576,7 @@ config ARCH_TEGRA select GENERIC_CLOCKEVENTS select GENERIC_GPIO select HAVE_CLK + select COMMON_CLKDEV select ARCH_HAS_BARRIERS if CACHE_L2X0 help This enables support for NVIDIA Tegra based systems (Tegra APX, diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index a0d2c5b..e20546a 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -1,3 +1,5 @@ obj-y += common.o obj-y += io.o obj-y += irq.o +obj-y += clock.o +obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c new file mode 100644 index 0000000..86c1965 --- /dev/null +++ b/arch/arm/mach-tegra/clock.c @@ -0,0 +1,191 @@ +/* + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * + * 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. + * + */ + +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/list.h> +#include <linux/init.h> +#include <linux/module.h> +#include <asm/clkdev.h> + +#include "clock.h" + +static LIST_HEAD(clocks); +static DEFINE_MUTEX(clocks_mutex); + +/** + * clk_preinit - initialize any fields in the struct clk before clk init + * @clk: struct clk * to initialize + * + * Initialize any struct clk fields needed before normal clk initialization + * can run. No return value. + */ +void clk_preinit(struct clk *c) +{ + c->lock = __SPIN_LOCK_UNLOCKED(c->lock); +} + +int clk_register(struct clk *c) +{ + mutex_lock(&clocks_mutex); + list_add(&c->node, &clocks); + mutex_unlock(&clocks_mutex); + return 0; +} + +int clk_enable(struct clk *c) +{ + int ret = 0; + unsigned long flags; + spin_lock_irqsave(&c->lock, flags); + if (c->refcnt == 0) { + if (c->parent) { + ret = clk_enable(c->parent); + if (ret) + goto err; + } + + if (c->ops && c->ops->enable) { + ret = c->ops->enable(c); + if (ret) { + if (c->parent) + clk_disable(c->parent); + goto err; + } + } + } + c->refcnt++; +err: + spin_unlock_irqrestore(&c->lock, flags); + return ret; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *c) +{ + unsigned long flags; + spin_lock_irqsave(&c->lock, flags); + if (c->refcnt == 0) { + WARN(1, "Attempting to disable clock %s with refcnt 0", c->name); + goto err; + } + if (c->refcnt == 1) { + if (c->parent) + clk_disable(c->parent); + + if (c->ops && c->ops->disable) + c->ops->disable(c); + } + c->refcnt--; +err: + spin_unlock_irqrestore(&c->lock, flags); +} +EXPORT_SYMBOL(clk_disable); + +int clk_set_parent(struct clk *c, struct clk *parent) +{ + unsigned long flags; + int ret = 0; + spin_lock_irqsave(&c->lock, flags); + if (c->ops && c->ops->set_parent) + ret = c->ops->set_parent(c, parent); + else + BUG(); + spin_unlock_irqrestore(&c->lock, flags); + return ret; +} +EXPORT_SYMBOL(clk_set_parent); + +struct clk *clk_get_parent(struct clk *c) +{ + return c->parent; +} +EXPORT_SYMBOL(clk_get_parent); + +int clk_set_rate(struct clk *c, unsigned long rate) +{ + int ret = 0; + unsigned long flags; + spin_lock_irqsave(&c->lock, flags); + if (c->ops && c->ops->set_rate) + ret = c->ops->set_rate(c, rate); + else + BUG(); + spin_unlock_irqrestore(&c->lock, flags); + return ret; +} +EXPORT_SYMBOL(clk_set_rate); + +unsigned long clk_get_rate(struct clk *c) +{ + int ret = 0; + unsigned long flags; + spin_lock_irqsave(&c->lock, flags); + if (c->ops && c->ops->get_rate) + ret = c->ops->get_rate(c); + else if (c->parent) + ret = clk_get_rate(c->parent); + else + BUG(); + spin_unlock_irqrestore(&c->lock, flags); + return ret; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_enable_init_clocks(void) +{ + struct clk *clkp; + + list_for_each_entry(clkp, &clocks, node) { + if (clkp->flags & ENABLE_ON_INIT) + clk_enable(clkp); + } +} +EXPORT_SYMBOL(clk_enable_init_clocks); + +int __init tegra_init_clock(void) +{ + int i; + struct clk_lookup *cl; + struct clk *c; + + for (cl = tegra_clk_lookups; cl->clk != NULL; cl++) { + clk_preinit(cl->clk); + if (cl->clk->ops && cl->clk->ops->init) + cl->clk->ops->init(cl->clk); + clkdev_add(cl); + clk_register(cl->clk); + } + + for (i = 0; i < tegra_num_periph_clks; i++) { + c = &tegra_periph_clks[i]; + cl = &tegra_periph_clk_lookups[i]; + cl->dev_id = c->dev_id; + cl->con_id = c->con_id; + cl->clk = c; + + clk_preinit(cl->clk); + if (cl->clk->ops && cl->clk->ops->init) + cl->clk->ops->init(cl->clk); + clkdev_add(cl); + clk_register(cl->clk); + } + + clk_enable_init_clocks(); + return 0; +} diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h new file mode 100644 index 0000000..100ade6 --- /dev/null +++ b/arch/arm/mach-tegra/clock.h @@ -0,0 +1,103 @@ +/* + * arch/arm/mach-tegra/include/mach/clock.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * + * 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. + * + */ + +#ifndef __MACH_TEGRA_CLOCK_H +#define __MACH_TEGRA_CLOCK_H + +#include <asm/clkdev.h> + +#define ENABLE_ON_INIT 0x00000001 +#define DIV_U71 0x00000002 +#define DIV_U71_FIXED 0x00000004 +#define DIV_2 0x00000008 +#define PLL_FIXED 0x00000010 +#define PLL_HAS_CPCON 0x00000020 +#define MUX 0x00000040 + +struct clk; + +struct clk_mux_sel { + struct clk *input; + u32 value; +}; + +struct clk_pll_table { + unsigned long input_rate; + unsigned long output_rate; + u16 n; + u16 m; + u8 p; + u8 cpcon; +}; + +struct clk_ops { + void (*init)(struct clk *); + int (*enable)(struct clk *); + void (*disable)(struct clk *); + void (*recalc)(struct clk *); + int (*set_parent)(struct clk *, struct clk *); + int (*set_rate)(struct clk *, unsigned long); + unsigned long (*get_rate)(struct clk *); + long (*round_rate)(struct clk *, unsigned long); +}; + +struct clk { + struct list_head node; + struct clk_ops *ops; + struct clk *parent; + unsigned long rate; + u32 flags; + u32 refcnt; + const char *name; + const char *dev_id; + const char *con_id; + u32 reg; + u32 reg_shift; + unsigned int clk_num; + spinlock_t lock; + + /* PLL */ + unsigned long input_min; + unsigned long input_max; + unsigned long cf_min; + unsigned long cf_max; + unsigned long vco_min; + unsigned long vco_max; + u32 m; + u32 n; + u32 p; + u32 cpcon; + const struct clk_pll_table *pll_table; + + /* DIV */ + + /* MUX */ + const struct clk_mux_sel *inputs; + u32 sel; + u32 reg_mask; +}; + +extern struct clk_lookup tegra_clk_lookups[]; +extern struct clk tegra_periph_clks[]; +extern struct clk_lookup tegra_periph_clk_lookups[]; +extern const int tegra_num_periph_clks; + +unsigned long clk_measure_input_freq(void); + +#endif diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index 20875ee..838bb5d 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c @@ -40,5 +40,6 @@ void __init tegra_init_cache(void) void __init tegra_common_init(void) { + tegra_init_clock(); tegra_init_cache(); } diff --git a/arch/arm/mach-tegra/include/mach/clkdev.h b/arch/arm/mach-tegra/include/mach/clkdev.h new file mode 100644 index 0000000..412f5c6 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/clkdev.h @@ -0,0 +1,32 @@ +/* + * arch/arm/mach-tegra/include/mach/clkdev.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * + * 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. + * + */ + +#ifndef __MACH_CLKDEV_H +#define __MACH_CLKDEV_H + +static inline int __clk_get(struct clk *clk) +{ + return 1; +} + +static inline void __clk_put(struct clk *clk) +{ +} + +#endif diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c new file mode 100644 index 0000000..83cbd5d --- /dev/null +++ b/arch/arm/mach-tegra/tegra2_clocks.c @@ -0,0 +1,837 @@ +/* + * arch/arm/mach-tegra/tegra2_clocks.c + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * + * 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. + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/clk.h> +#include <linux/list.h> +#include <linux/spinlock.h> +#include <linux/delay.h> + +#include <asm/io.h> +#include <asm/clkdev.h> + +#include <mach/io.h> +#include <mach/iomap.h> + +#include "clock.h" + +#define RST_DEVICES 0x004 +#define RST_DEVICES_SET 0x300 +#define RST_DEVICES_CLR 0x304 + + +#define CLK_OUT_ENB 0x010 +#define CLK_OUT_ENB_SET 0x320 +#define CLK_OUT_ENB_CLR 0x324 + +#define OSC_CTRL 0x50 +#define OSC_CTRL_OSC_FREQ_MASK (3<<30) +#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30) +#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30) +#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30) +#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30) + +#define OSC_FREQ_DET 0x58 +#define OSC_FREQ_DET_TRIG (1<<31) + +#define OSC_FREQ_DET_STATUS 0x5C +#define OSC_FREQ_DET_BUSY (1<<31) +#define OSC_FREQ_DET_CNT_MASK 0xFFFF + +#define PERIPH_CLK_SOURCE_MASK (3<<30) +#define PERIPH_CLK_SOURCE_SHIFT 30 +#define PERIPH_CLK_SOURCE_ENABLE (1<<28) +#define PERIPH_CLK_SOURCE_DIV_MASK 0xFF +#define PERIPH_CLK_SOURCE_DIV_SHIFT 0 + +#define PLL_BASE 0x0 +#define PLL_BASE_BYPASS (1<<31) +#define PLL_BASE_ENABLE (1<<30) +#define PLL_BASE_REF_ENABLE (1<<29) +#define PLL_BASE_OVERRIDE (1<<28) +#define PLL_BASE_LOCK (1<<27) +#define PLL_BASE_DIVP_MASK (0x7<<20) +#define PLL_BASE_DIVP_SHIFT 20 +#define PLL_BASE_DIVN_MASK (0x3FF<<8) +#define PLL_BASE_DIVN_SHIFT 8 +#define PLL_BASE_DIVM_MASK (0x1F) +#define PLL_BASE_DIVM_SHIFT 0 + +#define PLL_OUT_RATIO_MASK (0xFF<<8) +#define PLL_OUT_RATIO_SHIFT 8 +#define PLL_OUT_OVERRIDE (1<<2) +#define PLL_OUT_CLKEN (1<<1) +#define PLL_OUT_RESET_DISABLE (1<<0) + +#define PLL_MISC 0xc +#define PLL_MISC_DCCON (1<<20) +#define PLL_MISC_LOCK_ENABLE (1<<18) +#define PLL_MISC_CPCON_SHIFT 8 +#define PLL_MISC_LFCON_SHIFT 4 +#define PLL_MISC_VCOCON_SHIFT 0 + +static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE); + +/* Lock clk_reg_lock around any non-atomic access to a register + that is shared by multiple clocks. */ +static DEFINE_SPINLOCK(clk_reg_lock); + +#define clk_writel(value, reg) \ + __raw_writel(value, (u32)reg_clk_base + (reg)) +#define clk_readl(reg) \ + __raw_readl((u32)reg_clk_base + (reg)) + +unsigned long clk_measure_input_freq(void) { + u32 clock_autodetect; + clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET); + do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY); + clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS); + if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) { + return 12000000; + } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) { + return 13000000; + } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) { + return 19200000; + } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) { + return 26000000; + } else { + pr_err("%s: Unexpected clock autodetect value %d", __func__, clock_autodetect); + BUG(); + return 0; + } +} + +static int clk_div71_possible_rate(struct clk *c, unsigned long rate) +{ + unsigned long input_rate = clk_get_rate(c); + int divider_u71; + + divider_u71 = (input_rate*2)/rate; + if (rate * divider_u71 == input_rate*2) + return divider_u71 - 2; + else + return -1; +} + +/* Default clk ops */ +static int tegra2_clk_enable(struct clk *c) +{ + pr_debug("%s on clock %s\n", __func__, c->name); + return 0; +} + +static void tegra2_clk_disable(struct clk *c) +{ + pr_debug("%s on clock %s\n", __func__, c->name); +} + +static unsigned long tegra2_clk_get_rate(struct clk *c) +{ + pr_debug("%s on clock %s\n", __func__, c->name); + return c->rate; +} + +/* clk_m functions */ +static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c) +{ + u32 auto_clock_control = clk_readl(OSC_CTRL) & ~OSC_CTRL_OSC_FREQ_MASK; + + c->rate = clk_measure_input_freq(); + switch (c->rate) { + case 12000000: + auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ; + break; + case 13000000: + auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ; + break; + case 19200000: + auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ; + break; + case 26000000: + auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ; + break; + default: + pr_err("%s: Unexpected clock rate %ld", __func__, c->rate); + BUG(); + } + clk_writel(auto_clock_control, OSC_CTRL); + return c->rate; +} + +static void tegra2_clk_m_init(struct clk *c) +{ + pr_debug("%s on clock %s\n", __func__, c->name); + tegra2_clk_m_autodetect_rate(c); +} + +static int tegra2_clk_m_enable(struct clk *c) +{ + int ret = 0; + pr_debug("%s on clock %s\n", __func__, c->name); + return ret; +} + +static void tegra2_clk_m_disable(struct clk *c) +{ + pr_debug("%s on clock %s\n", __func__, c->name); + BUG(); +} + +static struct clk_ops tegra_clk_m_ops = { + .init = tegra2_clk_m_init, + .enable = tegra2_clk_m_enable, + .disable = tegra2_clk_m_disable, + .get_rate = tegra2_clk_get_rate, +}; + +/* PLL Functions */ +static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate) +{ + u32 val; + unsigned long input_rate; + const struct clk_pll_table *sel; + + pr_debug("%s on clock %s\n", __func__, c->name); + /* BUG_ON(c->refcnt != 0); */ + + input_rate = clk_get_rate(c->parent); + for (sel = c->pll_table; sel->input_rate != 0; sel++) { + if (sel->input_rate == input_rate && sel->output_rate == rate) { + c->n = sel->n; + c->m = sel->m; + c->p = sel->p; + c->cpcon = sel->cpcon; + val = clk_readl(c->reg + PLL_BASE); + if (c->flags & PLL_FIXED) + val |= PLL_BASE_OVERRIDE; + val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK | + PLL_BASE_DIVM_MASK); + val |= (c->m << PLL_BASE_DIVM_SHIFT) | + (c->n << PLL_BASE_DIVN_SHIFT); + BUG_ON(c->p > 2); + if (c->p == 2) + val |= 1 << PLL_BASE_DIVP_SHIFT; + clk_writel(val, c->reg + PLL_BASE); + c->rate = rate; + + if (c->flags & PLL_HAS_CPCON) { + val = c->cpcon << PLL_MISC_CPCON_SHIFT; + clk_writel(val, c->reg + PLL_MISC); + } + return 0; + } + } + return 1; +} + +static int tegra2_pll_clk_enable(struct clk *c) +{ + int ret = 0; + u32 val; + pr_debug("%s on clock %s\n", __func__, c->name); + + val = clk_readl(c->reg + PLL_BASE); + val &= ~PLL_BASE_BYPASS; + val |= PLL_BASE_ENABLE; + clk_writel(val, c->reg + PLL_BASE); + return ret; +} + +static void tegra2_pll_clk_disable(struct clk *c) +{ + u32 val; + pr_debug("%s on clock %s\n", __func__, c->name); + + val = clk_readl(c->reg); + val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); + clk_writel(val, c->reg); +} + +static struct clk_ops tegra_pll_ops = { + .enable = tegra2_pll_clk_enable, + .disable = tegra2_pll_clk_disable, + .set_rate = tegra2_pll_clk_set_rate, + .get_rate = tegra2_clk_get_rate, +}; + +/* Clock divider ops */ +static int tegra2_div_clk_set_rate(struct clk *c, unsigned long rate) +{ + int ret = 0; + unsigned long flags; + u32 val; + u32 new_val; + int divider_u71; + pr_debug("%s: %lu\n", __func__, rate); + if (c->flags & DIV_U71) { + divider_u71 = clk_div71_possible_rate(c->parent, rate); + if (divider_u71 >= 0) { + /* Divider values for multiple PLL outputs are + in the same register, so lock clk_reg_lock */ + spin_lock_irqsave(&clk_reg_lock, flags); + val = clk_readl(c->reg); + new_val = val >> c->reg_shift; + new_val &= 0xFFFF; + + if (c->flags & DIV_U71_FIXED) + new_val |= PLL_OUT_OVERRIDE; + new_val &= PLL_OUT_RATIO_MASK; + new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT; + + val &= ~(0xFFFF << c->reg_shift); + val |= new_val << c->reg_shift; + clk_writel(val, c->reg); + spin_unlock_irqrestore(&clk_reg_lock, flags); + return 1; + } + } else if (c->flags & DIV_2) { + if (clk_get_rate(c->parent) == rate * 2) + return 1; + } + BUG(); + return ret; +} + + +static struct clk_ops tegra_div_ops = { + .enable = tegra2_clk_enable, + .disable = tegra2_clk_disable, + .set_rate = tegra2_div_clk_set_rate, + .get_rate = tegra2_clk_get_rate, +}; + +/* Periph clk ops */ +static void tegra2_periph_clk_init(struct clk *c) +{ + u32 val; + const struct clk_mux_sel *mux = 0; + const struct clk_mux_sel *sel; + if (c->reg) { + val = clk_readl(c->reg); + for (sel = c->inputs; sel->input != NULL; sel++) { + if (val >> PERIPH_CLK_SOURCE_SHIFT == sel->value) + mux = sel; + } + BUG_ON(!mux); + + if (c->ops && c->ops->set_parent) + c->ops->set_parent(c, mux->input); + } else { + if (c->ops && c->ops->set_parent) + c->ops->set_parent(c, c->inputs[0].input); + } +} + +static int tegra2_periph_clk_enable(struct clk *c) +{ + u32 val = (1<<(c->clk_num%32)); + unsigned long reg = (c->clk_num / 32) * 8; + + clk_writel(val, CLK_OUT_ENB_SET + reg); + clk_writel(val, RST_DEVICES_CLR + reg); + return 0; +} + +static void tegra2_periph_clk_disable(struct clk *c) +{ + u32 val = (1<<(c->clk_num%32)); + unsigned long reg = (c->clk_num / 32) * 8; + + clk_writel(val, CLK_OUT_ENB_CLR + reg); + clk_writel(val, RST_DEVICES_SET + reg); +} + +static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p) +{ + int ret = 0; + u32 val; + const struct clk_mux_sel *sel; + for (sel = c->inputs; sel->input != NULL; sel++) { + if (sel->input == p) { + c->parent = p; + val = clk_readl(c->reg); + val &= ~PERIPH_CLK_SOURCE_MASK; + val |= (sel->value) << PERIPH_CLK_SOURCE_SHIFT; + clk_writel(val, c->reg); + } + } + + return ret; +} + +static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate) +{ + int ret = 0; + u32 val; + int divider_u71; + const struct clk_mux_sel *sel; + pr_debug("%s: %lu\n", __func__, rate); + for (sel = c->inputs; sel->input != NULL; sel++) { + if (c->flags & DIV_U71) { + divider_u71 = clk_div71_possible_rate(sel->input, rate); + if (divider_u71 >= 0) { + /* FIXME: ensure we don't go through a too-high rate */ + if (c->ops && c->ops->set_parent) + c->ops->set_parent(c, sel->input); + udelay(1); + val = clk_readl(c->reg); + val &= ~PERIPH_CLK_SOURCE_DIV_MASK; + val |= divider_u71; + clk_writel(val, c->reg); + return 1; + } + } else { + if (clk_get_rate(sel->input) == rate) { + if (c->ops && c->ops->set_parent) + c->ops->set_parent(c, sel->input); + return 1; + } + } + } + BUG(); + return ret; +} + +static struct clk_ops tegra_periph_clk_ops = { + .init = &tegra2_periph_clk_init, + .enable = &tegra2_periph_clk_enable, + .disable = &tegra2_periph_clk_disable, + .set_parent = &tegra2_periph_clk_set_parent, + .set_rate = &tegra2_periph_clk_set_rate, +}; + +static struct clk tegra_clk_32k = { + .name = "tegra_clk_32k", + .rate = 32678, + .ops = NULL, +}; + +static struct clk tegra_clk_input = { + .name = "tegra_clk_input", + .flags = ENABLE_ON_INIT, + .rate = 12000000, + .ops = NULL, +}; + +static struct clk_pll_table tegra_pll_s_table[] = { + {32768, 12000000, 366, 1, 1, 0}, + {32768, 13000000, 397, 1, 1, 0}, + {32768, 19200000, 586, 1, 1, 0}, + {32768, 26000000, 793, 1, 1, 0}, + {0, 0, 0, 0, 0, 0}, +}; + +static struct clk tegra_pll_s = { + .name = "tegra_pll_s", + .ops = &tegra_pll_ops, + .reg = 0xf0, + .input_min = 32768, + .input_max = 32768, + .parent = &tegra_clk_32k, + .cf_min = 0, /* FIXME */ + .cf_max = 0, /* FIXME */ + .vco_min = 12000000, + .vco_max = 26000000, + .pll_table = tegra_pll_s_table, +}; + +static struct clk_mux_sel tegra_clk_m_sel[] = { + { .input = &tegra_clk_32k, .value = 0}, + { .input = &tegra_pll_s, .value = 1}, + { 0, 0}, +}; +static struct clk tegra_clk_m = { + .name = "tegra_clk_m", + .flags = ENABLE_ON_INIT, + .ops = &tegra_clk_m_ops, + .inputs = tegra_clk_m_sel, + .reg = 0x1fc, + .reg_mask = (1<<28), + .reg_shift = 28, +}; + +static struct clk_pll_table tegra_pll_c_table[] = { + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct clk tegra_pll_c = { + .name = "tegra_pll_c", + .flags = PLL_HAS_CPCON, + .ops = &tegra_pll_ops, + .reg = 0x80, + .input_min = 2000000, + .input_max = 31000000, + .parent = &tegra_clk_m, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1400000000, + .pll_table = tegra_pll_c_table, +}; + +static struct clk tegra_pll_c_out1 = { + .name = "tegra_pll_c_out1", + .ops = &tegra_div_ops, + .flags = DIV_U71, + .parent = &tegra_pll_c, + .reg = 0x84, + .reg_shift = 0, +}; + +static struct clk_pll_table tegra_pll_m_table[] = { + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct clk tegra_pll_m = { + .name = "tegra_pll_m", + .flags = PLL_HAS_CPCON, + .ops = &tegra_pll_ops, + .reg = 0x90, + .input_min = 2000000, + .input_max = 31000000, + .parent = &tegra_clk_m, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1200000000, + .pll_table = tegra_pll_m_table, +}; + +static struct clk tegra_pll_m_out1 = { + .name = "tegra_pll_m_out1", + .ops = &tegra_div_ops, + .flags = DIV_U71, + .parent = &tegra_pll_m, + .reg = 0x94, + .reg_shift = 0, +}; + +static struct clk_pll_table tegra_pll_p_table[] = { + { 12000000, 216000000, 432, 12, 2, 8}, + { 13000000, 216000000, 432, 13, 2, 8}, + { 19200000, 216000000, 90, 4, 2, 1}, + { 26000000, 216000000, 432, 26, 2, 8}, + { 12000000, 432000000, 432, 12, 1, 8}, + { 13000000, 432000000, 432, 13, 1, 8}, + { 19200000, 432000000, 90, 4, 1, 1}, + { 26000000, 432000000, 432, 26, 1, 8}, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct clk tegra_pll_p = { + .name = "tegra_pll_p", + .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON, + .ops = &tegra_pll_ops, + .reg = 0xa0, + .input_min = 2000000, + .input_max = 31000000, + .parent = &tegra_clk_m, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1400000000, + .pll_table = tegra_pll_p_table, +}; + +static struct clk tegra_pll_p_out1 = { + .name = "tegra_pll_p_out1", + .ops = &tegra_div_ops, + .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, + .parent = &tegra_pll_p, + .reg = 0xa4, + .reg_shift = 0, +}; + +static struct clk tegra_pll_p_out2 = { + .name = "tegra_pll_p_out2", + .ops = &tegra_div_ops, + .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, + .parent = &tegra_pll_p, + .reg = 0xa4, + .reg_shift = 16, +}; + +static struct clk tegra_pll_p_out3 = { + .name = "tegra_pll_p_out3", + .ops = &tegra_div_ops, + .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, + .parent = &tegra_pll_p, + .reg = 0xa8, + .reg_shift = 0, +}; + +static struct clk tegra_pll_p_out4 = { + .name = "tegra_pll_p_out4", + .ops = &tegra_div_ops, + .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, + .parent = &tegra_pll_p, + .reg = 0xa8, + .reg_shift = 16, +}; + +static struct clk_pll_table tegra_pll_a_table[] = { + { 28800000, 56448000, 49, 25, 1, 1}, + { 28800000, 73728000, 64, 25, 1, 1}, + { 28800000, 11289600, 49, 25, 1, 1}, + { 28800000, 12288000, 64, 25, 1, 1}, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct clk tegra_pll_a = { + .name = "tegra_pll_a", + .flags = PLL_HAS_CPCON, + .ops = &tegra_pll_ops, + .reg = 0xb0, + .input_min = 2000000, + .input_max = 31000000, + .parent = &tegra_pll_p_out1, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1400000000, + .pll_table = tegra_pll_a_table, +}; + +static struct clk tegra_pll_a_out0 = { + .name = "tegra_pll_a_out0", + .ops = &tegra_div_ops, + .flags = DIV_U71, + .parent = &tegra_pll_a, + .reg = 0xb4, + .reg_shift = 0, +}; + +static struct clk_pll_table tegra_pll_d_table[] = { + { 12000000, 1000000000, 1000, 12, 1, 12}, + { 13000000, 1000000000, 1000, 13, 1, 12}, + { 19200000, 1000000000, 625, 12, 1, 8}, + { 26000000, 1000000000, 1000, 26, 1, 12}, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct clk tegra_pll_d = { + .name = "tegra_pll_d", + .flags = PLL_HAS_CPCON, + .ops = &tegra_pll_ops, + .reg = 0xd0, + .input_min = 2000000, + .input_max = 40000000, + .parent = &tegra_clk_m, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 40000000, + .vco_max = 1000000000, + .pll_table = tegra_pll_d_table, +}; + +static struct clk tegra_pll_d_out0 = { + .name = "tegra_pll_d_out0", + .ops = &tegra_div_ops, + .flags = DIV_2, + .parent = &tegra_pll_d, +}; + +static struct clk_pll_table tegra_pll_u_table[] = { + { 12000000, 480000000, 960, 12, 1, 0}, + { 13000000, 480000000, 960, 13, 1, 0}, + { 19200000, 480000000, 200, 4, 1, 0}, + { 26000000, 480000000, 960, 26, 1, 0}, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct clk tegra_pll_u = { + .name = "tegra_pll_u", + .flags = 0, + .ops = &tegra_pll_ops, + .reg = 0xc0, + .input_min = 2000000, + .input_max = 40000000, + .parent = &tegra_clk_m, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 480000000, + .vco_max = 960000000, + .pll_table = tegra_pll_u_table, +}; + +static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = { + { .input = &tegra_pll_m, .value = 0}, + { .input = &tegra_pll_c, .value = 1}, + { .input = &tegra_pll_p, .value = 2}, + { .input = &tegra_pll_a_out0, .value = 3}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = { + { .input = &tegra_pll_p, .value = 0}, + { .input = &tegra_pll_c, .value = 1}, + { .input = &tegra_pll_m, .value = 2}, + { .input = &tegra_clk_m, .value = 3}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_plla_audio_pllp_clkm[] = { + {.input = &tegra_pll_a, .value = 0}, + /* FIXME: no mux defined for tegra_audio + {.input = &tegra_audio, .value = 1},*/ + {.input = &tegra_pll_p, .value = 2}, + {.input = &tegra_clk_m, .value = 3}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = { + {.input = &tegra_pll_p, .value = 0}, + {.input = &tegra_pll_d_out0, .value = 1}, + {.input = &tegra_pll_c, .value = 2}, + {.input = &tegra_clk_m, .value = 3}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_pllp_pllc_audio_clkm_clk32[] = { + {.input = &tegra_pll_p, .value = 0}, + {.input = &tegra_pll_c, .value = 1}, + /* FIXME: no mux defined for tegra_audio + {.input = &tegra_audio, .value = 2},*/ + {.input = &tegra_clk_m, .value = 3}, + {.input = &tegra_clk_32k, .value = 4}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_pllp_pllc_pllm[] = { + {.input = &tegra_pll_p, .value = 0}, + {.input = &tegra_pll_c, .value = 1}, + {.input = &tegra_pll_m, .value = 2}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_clk_m[] = { + { .input = &tegra_clk_m, .value = 0}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_clk_32k[] = { + { .input = &tegra_clk_32k, .value = 0}, + { 0, 0}, +}; + +#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _inputs, _flags) \ + { \ + .name = _name, \ + .dev_id = _dev, \ + .con_id = _con, \ + .ops = &tegra_periph_clk_ops, \ + .clk_num = _clk_num, \ + .reg = _reg, \ + .inputs = _inputs, \ + .flags = _flags, \ + } + +struct clk tegra_periph_clks[] = { + PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, mux_clk_32k, 0), + PERIPH_CLK("timer", "timer", NULL, 5, 0, mux_clk_m, 0), + PERIPH_CLK("i2s1", "i2s.0", NULL, 11, 0x100, mux_plla_audio_pllp_clkm, MUX | DIV_U71), + PERIPH_CLK("i2s2", "i2s.1", NULL, 18, 0x104, mux_plla_audio_pllp_clkm, MUX | DIV_U71), + /* FIXME: spdif has 2 clocks but 1 enable */ + PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, mux_plla_audio_pllp_clkm, MUX | DIV_U71), + PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, mux_pllp_pllc_pllm, MUX | DIV_U71), + PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71), + PERIPH_CLK("spi", "spi", NULL, 43, 0x114, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("xio", "xio", NULL, 45, 0x120, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("twc", "twc", NULL, 16, 0x12c, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sbc1", "sbc.0", NULL, 41, 0x134, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sbc2", "sbc.1", NULL, 44, 0x118, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sbc3", "sbc.2", NULL, 46, 0x11c, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sbc4", "sbc.3", NULL, 68, 0x1b4, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("ide", "ide", NULL, 25, 0x144, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("ndflash", "tegra_nand", NULL, 13, 0x160, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + /* FIXME: vfir shares an enable with uartb */ + PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x160, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + /* FIXME: what is la? */ + PERIPH_CLK("la", "la", NULL, 76, 0x1f8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("owr", "owr", NULL, 71, 0x1cc, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("nor", "nor", NULL, 42, 0x1d0, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("i2c1", "i2c.0", NULL, 12, 0x124, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("i2c2", "i2c.1", NULL, 54, 0x198, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("i2c3", "i2c.2", NULL, 67, 0x1b8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("dvc", "dvc", NULL, 47, 0x128, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("uarta", "uart.0", NULL, 6, 0x178, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("uartb", "uart.1", NULL, 7, 0x17c, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("uartc", "uart.2", NULL, 55, 0x1a0, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("uartd", "uart.3", NULL, 65, 0x1c0, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("uarte", "uart.4", NULL, 66, 0x1c4, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("3d", "3d", NULL, 24, 0x158, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), + PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), + /* FIXME: vi and vi_sensor share an enable */ + PERIPH_CLK("vi", "vi", NULL, 20, 0x148, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), + PERIPH_CLK("vi_sensor", "vi_sensor", NULL, 20, 0x1a8, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), + PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), + PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), + PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), + /* FIXME: cve and tvo share an enable */ + PERIPH_CLK("cve", "cve", NULL, 49, 0x140, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), + PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), + PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), + PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), + PERIPH_CLK("disp1", "tegrafb.0", NULL, 27, 0x138, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), + PERIPH_CLK("disp2", "tegrafb.1", NULL, 26, 0x13c, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), + PERIPH_CLK("usbd", "usb.0", NULL, 22, 0, mux_clk_m, 0), + PERIPH_CLK("usb2", "usb.1", NULL, 58, 0, mux_clk_m, 0), + PERIPH_CLK("usb3", "usb.2", NULL, 59, 0, mux_clk_m, 0), +}; +const int tegra_num_periph_clks = ARRAY_SIZE(tegra_periph_clks); + +struct clk_lookup tegra_periph_clk_lookups[ARRAY_SIZE(tegra_periph_clks)]; + +#define CLK(dev, con, ck) \ + { \ + .dev_id = dev, \ + .con_id = con, \ + .clk = ck, \ + } + +struct clk_lookup tegra_clk_lookups[] = { + /* external root sources */ + CLK(NULL, "input_clk", &tegra_clk_input), + CLK(NULL, "32k_clk", &tegra_clk_32k), + CLK(NULL, "pll_s", &tegra_pll_s), + CLK(NULL, "clk_m", &tegra_clk_m), + CLK(NULL, "pll_m", &tegra_pll_m), + CLK(NULL, "pll_m_out1", &tegra_pll_m_out1), + CLK(NULL, "pll_c", &tegra_pll_c), + CLK(NULL, "pll_c_out1", &tegra_pll_c_out1), + CLK(NULL, "pll_p", &tegra_pll_p), + CLK(NULL, "pll_p_out1", &tegra_pll_p_out1), + CLK(NULL, "pll_p_out2", &tegra_pll_p_out2), + CLK(NULL, "pll_p_out3", &tegra_pll_p_out3), + CLK(NULL, "pll_p_out4", &tegra_pll_p_out4), + CLK(NULL, "pll_a", &tegra_pll_a), + CLK(NULL, "pll_a_out0", &tegra_pll_a_out0), + CLK(NULL, "pll_d", &tegra_pll_d), + CLK(NULL, "pll_d_out0", &tegra_pll_d_out0), + CLK(NULL, "pll_u", &tegra_pll_u), + CLK(NULL, NULL, NULL), +}; -- 1.6.5.6 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [RFC/PATCH 04/10] [ARM] tegra: SMP support 2010-03-16 6:41 ` [RFC/PATCH 03/10] [ARM] tegra: Add clock support konkers at google.com @ 2010-03-16 6:41 ` konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 05/10] [ARM] tegra: Add timer support konkers at google.com 2010-03-18 8:42 ` [RFC/PATCH 03/10] [ARM] tegra: Add clock support Russell King - ARM Linux 1 sibling, 1 reply; 37+ messages in thread From: konkers at google.com @ 2010-03-16 6:41 UTC (permalink / raw) To: linux-arm-kernel From: Colin Cross <ccross@android.com> Signed-off-by: Colin Cross <ccross@android.com> Signed-off-by: Erik Gilling <konkers@android.com> --- arch/arm/Kconfig | 12 ++- arch/arm/mach-tegra/Makefile | 2 + arch/arm/mach-tegra/headsmp.S | 61 +++++++++++++ arch/arm/mach-tegra/hotplug.c | 140 ++++++++++++++++++++++++++++ arch/arm/mach-tegra/include/mach/smp.h | 30 ++++++ arch/arm/mach-tegra/localtimer.c | 25 +++++ arch/arm/mach-tegra/platsmp.c | 156 ++++++++++++++++++++++++++++++++ 7 files changed, 422 insertions(+), 4 deletions(-) create mode 100644 arch/arm/mach-tegra/headsmp.S create mode 100644 arch/arm/mach-tegra/hotplug.c create mode 100644 arch/arm/mach-tegra/include/mach/smp.h create mode 100644 arch/arm/mach-tegra/localtimer.c create mode 100644 arch/arm/mach-tegra/platsmp.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a5be2d6..0b9002d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1045,10 +1045,12 @@ source "kernel/time/Kconfig" config SMP bool "Symmetric Multi-Processing (EXPERIMENTAL)" depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\ - MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500) + MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \ + ARCH_U8500 || ARCH_TEGRA) depends on GENERIC_CLOCKEVENTS select USE_GENERIC_SMP_HELPERS - select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500) + select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500 || \ + ARCH_TEGRA) help This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If @@ -1117,9 +1119,11 @@ config HOTPLUG_CPU config LOCAL_TIMERS bool "Use local timer interrupts" depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \ - REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500) + REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \ + ARCH_U8500 || ARCH_TEGRA) default y - select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500) + select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500 || \ + ARCH_TEGRA) help Enable support for local timers on SMP platforms, rather then the legacy IPI broadcast method. Local timers allows the system diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index e20546a..f339559 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -3,3 +3,5 @@ obj-y += io.o obj-y += irq.o obj-y += clock.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o +obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o +obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S new file mode 100644 index 0000000..b5349b2 --- /dev/null +++ b/arch/arm/mach-tegra/headsmp.S @@ -0,0 +1,61 @@ +#include <linux/linkage.h> +#include <linux/init.h> + + .section ".text.head", "ax" + __CPUINIT + +/* + * Tegra specific entry point for secondary CPUs. + * The secondary kernel init calls v7_flush_dcache_all before it enables + * the L1; however, the L1 comes out of reset in an undefined state, so + * the clean + invalidate performed by v7_flush_dcache_all causes a bunch + * of cache lines with uninitialized data and uninitialized tags to get + * written out to memory, which does really unpleasant things to the main + * processor. We fix this by performing an invalidate, rather than a + * clean + invalidate, before jumping into the kernel. + */ +ENTRY(v7_invalidate_l1) + mov r0, #0 + mcr p15, 2, r0, c0, c0, 0 + mrc p15, 1, r0, c0, c0, 0 + + ldr r1, =0x7fff + and r2, r1, r0, lsr #13 + + ldr r1, =0x3ff + + and r3, r1, r0, lsr #3 @ NumWays - 1 + add r2, r2, #1 @ NumSets + + and r0, r0, #0x7 + add r0, r0, #4 @ SetShift + + clz r1, r3 @ WayShift + add r4, r3, #1 @ NumWays +1: sub r2, r2, #1 @ NumSets-- + mov r3, r4 @ Temp = NumWays +2: subs r3, r3, #1 @ Temp-- + mov r5, r3, lsl r1 + mov r6, r2, lsl r0 + orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift) + mcr p15, 0, r5, c7, c6, 2 + bgt 2b + cmp r2, #0 + bgt 1b + dsb + isb + mov pc, lr +ENDPROC(v7_invalidate_l1) + +ENTRY(tegra_secondary_startup) + msr cpsr_fsxc, #0xd3 + bl v7_invalidate_l1 + mrc p15, 0, r0, c0, c0, 5 + and r0, r0, #15 + ldr r1, =0x6000f100 + str r0, [r1] +1: ldr r2, [r1] + cmp r0, r2 + beq 1b + b secondary_startup +ENDPROC(tegra_secondary_startup) diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c new file mode 100644 index 0000000..464316c --- /dev/null +++ b/arch/arm/mach-tegra/hotplug.c @@ -0,0 +1,140 @@ +/* + * linux/arch/arm/mach-realview/hotplug.c + * + * Copyright (C) 2002 ARM Ltd. + * All Rights Reserved + * + * 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 <linux/kernel.h> +#include <linux/errno.h> +#include <linux/smp.h> +#include <linux/completion.h> + +#include <asm/cacheflush.h> + +static DECLARE_COMPLETION(cpu_killed); + +static inline void cpu_enter_lowpower(void) +{ + unsigned int v; + + flush_cache_all(); + asm volatile( + " mcr p15, 0, %1, c7, c5, 0\n" + " mcr p15, 0, %1, c7, c10, 4\n" + /* + * Turn off coherency + */ + " mrc p15, 0, %0, c1, c0, 1\n" + " bic %0, %0, #0x20\n" + " mcr p15, 0, %0, c1, c0, 1\n" + " mrc p15, 0, %0, c1, c0, 0\n" + " bic %0, %0, #0x04\n" + " mcr p15, 0, %0, c1, c0, 0\n" + : "=&r" (v) + : "r" (0) + : "cc"); +} + +static inline void cpu_leave_lowpower(void) +{ + unsigned int v; + + asm volatile( + "mrc p15, 0, %0, c1, c0, 0\n" + " orr %0, %0, #0x04\n" + " mcr p15, 0, %0, c1, c0, 0\n" + " mrc p15, 0, %0, c1, c0, 1\n" + " orr %0, %0, #0x20\n" + " mcr p15, 0, %0, c1, c0, 1\n" + : "=&r" (v) + : + : "cc"); +} + +static inline void platform_do_lowpower(unsigned int cpu) +{ + /* + * there is no power-control hardware on this platform, so all + * we can do is put the core into WFI; this is safe as the calling + * code will have already disabled interrupts + */ + for (;;) { + /* + * here's the WFI + */ + asm(".word 0xe320f003\n" + : + : + : "memory", "cc"); + + /*if (pen_release == cpu) {*/ + /* + * OK, proper wakeup, we're done + */ + break; + /*}*/ + + /* + * getting here, means that we have come out of WFI without + * having been woken up - this shouldn't happen + * + * The trouble is, letting people know about this is not really + * possible, since we are currently running incoherently, and + * therefore cannot safely call printk() or anything else + */ +#ifdef DEBUG + printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu); +#endif + } +} + +int platform_cpu_kill(unsigned int cpu) +{ + return wait_for_completion_timeout(&cpu_killed, 5000); +} + +/* + * platform-specific code to shutdown a CPU + * + * Called with IRQs disabled + */ +void platform_cpu_die(unsigned int cpu) +{ +#ifdef DEBUG + unsigned int this_cpu = hard_smp_processor_id(); + + if (cpu != this_cpu) { + printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n", + this_cpu, cpu); + BUG(); + } +#endif + + printk(KERN_NOTICE "CPU%u: shutdown\n", cpu); + complete(&cpu_killed); + + /* + * we're ready for shutdown now, so do it + */ + cpu_enter_lowpower(); + platform_do_lowpower(cpu); + + /* + * bring this CPU back into the world of cache + * coherency, and then restore interrupts + */ + cpu_leave_lowpower(); +} + +int mach_cpu_disable(unsigned int cpu) +{ + /* + * we don't allow CPU 0 to be shutdown (it is still too special + * e.g. clock tick interrupts) + */ + return cpu == 0 ? -EPERM : 0; +} diff --git a/arch/arm/mach-tegra/include/mach/smp.h b/arch/arm/mach-tegra/include/mach/smp.h new file mode 100644 index 0000000..8b42dab --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/smp.h @@ -0,0 +1,30 @@ +#ifndef ASMARM_ARCH_SMP_H +#define ASMARM_ARCH_SMP_H + + +#include <asm/hardware/gic.h> + +#define hard_smp_processor_id() \ + ({ \ + unsigned int cpunum; \ + __asm__("mrc p15, 0, %0, c0, c0, 5" \ + : "=r" (cpunum)); \ + cpunum &= 0x0F; \ + }) + +/* + * We use IRQ1 as the IPI + */ +static inline void smp_cross_call(const struct cpumask *mask) +{ + gic_raise_softirq(mask, 1); +} + +/* + * Do nothing on MPcore. + */ +static inline void smp_cross_call_done(cpumask_t callmap) +{ +} + +#endif diff --git a/arch/arm/mach-tegra/localtimer.c b/arch/arm/mach-tegra/localtimer.c new file mode 100644 index 0000000..f81ca7c --- /dev/null +++ b/arch/arm/mach-tegra/localtimer.c @@ -0,0 +1,25 @@ +/* + * arch/arm/mach-tegra/localtimer.c + * + * Copyright (C) 2002 ARM Ltd. + * All Rights Reserved + * + * 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 <linux/init.h> +#include <linux/smp.h> +#include <linux/clockchips.h> +#include <asm/irq.h> +#include <asm/smp_twd.h> +#include <asm/localtimer.h> + +/* + * Setup the local clock events for a CPU. + */ +void __cpuinit local_timer_setup(struct clock_event_device *evt) +{ + evt->irq = IRQ_LOCALTIMER; + twd_timer_setup(evt); +} diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c new file mode 100644 index 0000000..1c0fd92 --- /dev/null +++ b/arch/arm/mach-tegra/platsmp.c @@ -0,0 +1,156 @@ +/* + * linux/arch/arm/mach-tegra/platsmp.c + * + * Copyright (C) 2002 ARM Ltd. + * All Rights Reserved + * + * Copyright (C) 2009 Palm + * All Rights Reserved + * + * 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 <linux/init.h> +#include <linux/errno.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/jiffies.h> +#include <linux/smp.h> +#include <linux/io.h> + +#include <asm/cacheflush.h> +#include <mach/hardware.h> +#include <asm/mach-types.h> +#include <asm/localtimer.h> +#include <asm/smp_scu.h> + +#include <mach/iomap.h> + +extern void tegra_secondary_startup(void); + +static DEFINE_SPINLOCK(boot_lock); +static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); + +#define EVP_CPU_RESET_VECTOR \ + (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) +#define CLK_RST_CONTROLLER_CLK_CPU_CMPLX \ + (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x4c) +#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR \ + (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x344) + +void __cpuinit platform_secondary_init(unsigned int cpu) +{ + trace_hardirqs_off(); + + /* + * if any interrupts are already enabled for the primary + * core (e.g. timer irq), then they will not have been enabled + * for us: do so + */ + gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x100); + + /* + * Synchronise with the boot thread. + */ + spin_lock(&boot_lock); + spin_unlock(&boot_lock); +} + +int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + unsigned long old_boot_vector; + unsigned long boot_vector; + unsigned long timeout; + u32 reg; + + /* + * set synchronisation state between this boot processor + * and the secondary one + */ + spin_lock(&boot_lock); + + + /* set the reset vector to point to the secondary_startup routine */ + + boot_vector = virt_to_phys(tegra_secondary_startup); + old_boot_vector = readl(EVP_CPU_RESET_VECTOR); + writel(boot_vector, EVP_CPU_RESET_VECTOR); + + /* enable cpu clock on cpu1 */ + reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX); + writel(reg & ~(1<<9), CLK_RST_CONTROLLER_CLK_CPU_CMPLX); + + reg = (1<<13) | (1<<9) | (1<<5) | (1<<1); + writel(reg, CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR); + + smp_wmb(); + flush_cache_all(); + + /* unhalt the cpu */ + writel(0, IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + 0x14); + + timeout = jiffies + (1 * HZ); + while (time_before(jiffies, timeout)) { + if (readl(EVP_CPU_RESET_VECTOR) != boot_vector) + break; + udelay(10); + } + + /* put the old boot vector back */ + writel(old_boot_vector, EVP_CPU_RESET_VECTOR); + + /* + * now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ + spin_unlock(&boot_lock); + + return 0; +} + +/* + * Initialise the CPU possible map early - this describes the CPUs + * which may be present or become present in the system. + */ +void __init smp_init_cpus(void) +{ + unsigned int i, ncores = scu_get_core_count(scu_base); + + for (i = 0; i < ncores; i++) + cpu_set(i, cpu_possible_map); +} + +void __init smp_prepare_cpus(unsigned int max_cpus) +{ + unsigned int ncores = scu_get_core_count(scu_base); + unsigned int cpu = smp_processor_id(); + int i; + + smp_store_cpu_info(cpu); + + /* + * are we trying to boot more cores than exist? + */ + if (max_cpus > ncores) + max_cpus = ncores; + + /* + * Initialise the present map, which describes the set of CPUs + * actually populated at the present time. + */ + for (i = 0; i < max_cpus; i++) + set_cpu_present(i, true); + + /* + * Initialise the SCU if there are more than one CPU and let + * them know where to start. Note that, on modern versions of + * MILO, the "poke" doesn't actually do anything until each + * individual core is sent a soft interrupt to get it out of + * WFI + */ + if (max_cpus > 1) { + percpu_timer_setup(); + scu_enable(scu_base); + } +} -- 1.6.5.6 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [RFC/PATCH 05/10] [ARM] tegra: Add timer support 2010-03-16 6:41 ` [RFC/PATCH 04/10] [ARM] tegra: SMP support konkers at google.com @ 2010-03-16 6:41 ` konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 06/10] [ARM] tegra: add GPIO support konkers at google.com 0 siblings, 1 reply; 37+ messages in thread From: konkers at google.com @ 2010-03-16 6:41 UTC (permalink / raw) To: linux-arm-kernel From: Colin Cross <ccross@android.com> Signed-off-by: Colin Cross <ccross@android.com> Signed-off-by: Erik Gilling <konkers@android.com> --- arch/arm/mach-tegra/Makefile | 1 + arch/arm/mach-tegra/timer.c | 185 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-tegra/timer.c diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index f339559..01f47fd 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -2,6 +2,7 @@ obj-y += common.o obj-y += io.o obj-y += irq.o obj-y += clock.o +obj-y += timer.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c new file mode 100644 index 0000000..f3b8e79 --- /dev/null +++ b/arch/arm/mach-tegra/timer.c @@ -0,0 +1,185 @@ +/* + * arch/arch/mach-tegra/timer.c + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Colin Cross <ccross@google.com> + * + * 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. + * + */ + +#include <linux/init.h> +#include <linux/time.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/clockchips.h> +#include <linux/clocksource.h> +#include <linux/clk.h> +#include <asm/mach/time.h> +#include <asm/io.h> +#include <asm/mach/time.h> +#include <asm/localtimer.h> +#include <mach/iomap.h> + +#include "board.h" +#include "clock.h" + +#define TIMERUS_CNTR_1US 0x10 +#define TIMERUS_USEC_CFG 0x14 +#define TIMERUS_CNTR_FREEZE 0x4c + +#define TIMER1_BASE 0x0 +#define TIMER2_BASE 0x8 +#define TIMER3_BASE 0x50 +#define TIMER4_BASE 0x58 + +#define TIMER_PTV 0x0 +#define TIMER_PCR 0x4 + +#define TIMER1_IRQ 32 +#define TIMER2_IRQ 33 +#define TIMER3_IRQ 41 +#define TIMER4_IRQ 42 + +struct tegra_timer; + +static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE); + +#define timer_writel(value, reg) \ + __raw_writel(value, (u32)timer_reg_base + (reg)) +#define timer_readl(reg) \ + __raw_readl((u32)timer_reg_base + (reg)) + +static int tegra_timer_set_next_event(unsigned long cycles, + struct clock_event_device *evt) +{ + u32 reg; + + reg = 0x80000000 | ((1000000/HZ)*(cycles+1)-1); + timer_writel(reg, TIMER1_BASE + TIMER_PTV); + + return 0; +} + +static void tegra_timer_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + u32 reg; + + timer_writel(0, TIMER1_BASE + TIMER_PTV); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + reg = 0xC0000000 | ((1000000/HZ)-1); + timer_writel(reg, TIMER1_BASE + TIMER_PTV); + break; + case CLOCK_EVT_MODE_ONESHOT: + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_RESUME: + break; + } +} + +static cycle_t tegra_clocksource_read(struct clocksource *cs) +{ + return timer_readl(TIMERUS_CNTR_1US); +} + +static struct clock_event_device tegra_clockevent = { + .name = "timer0", + .rating = 300, + .features = CLOCK_EVT_FEAT_ONESHOT, CLOCK_EVT_FEAT_PERIODIC, + .mult = 16777, + .shift = 24, + .set_next_event = tegra_timer_set_next_event, + .set_mode = tegra_timer_set_mode, +}; + +static struct clocksource tegra_clocksource = { + .name = "timer_us", + .rating = 300, + .read = tegra_clocksource_read, + .mask = 0xFFFFFFFFUL, + .mult = 1000, + .shift = 0, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = (struct clock_event_device *)dev_id; + timer_writel(1<<30, TIMER1_BASE + TIMER_PCR); + evt->event_handler(evt); + return IRQ_HANDLED; +} + +static struct irqaction tegra_timer_irq = { + .name = "timer0", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_HIGH, + .handler = tegra_timer_interrupt, + .dev_id = &tegra_clockevent, + .irq = TIMER1_IRQ, +}; + +static void __init tegra_init_timer(void) +{ + unsigned long rate = clk_measure_input_freq(); + int ret; + +#ifdef CONFIG_HAVE_ARM_TWD + twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600); +#endif + + switch (rate) { + case 12000000: + timer_writel(0x000b, TIMERUS_USEC_CFG); + break; + case 13000000: + timer_writel(0x000c, TIMERUS_USEC_CFG); + break; + case 19200000: + timer_writel(0x045f, TIMERUS_USEC_CFG); + break; + case 26000000: + timer_writel(0x0019, TIMERUS_USEC_CFG); + break; + default: + WARN(1, "Unknown clock rate"); + } + + if (clocksource_register(&tegra_clocksource)) { + printk(KERN_ERR "Failed to register clocksource\n"); + BUG(); + } + + ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq); + if (ret) { + printk(KERN_ERR "Failed to register timer IRQ: %d\n", ret); + BUG(); + } + + tegra_clockevent.max_delta_ns = + clockevent_delta2ns(0x1fffffff, &tegra_clockevent); + tegra_clockevent.max_delta_ns = + clockevent_delta2ns(0x1, &tegra_clockevent); + tegra_clockevent.cpumask = cpu_all_mask; + tegra_clockevent.irq = TIMER1_IRQ; + clockevents_register_device(&tegra_clockevent); + + return; +} + +struct sys_timer tegra_timer = { + .init = tegra_init_timer, +}; -- 1.6.5.6 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [RFC/PATCH 06/10] [ARM] tegra: add GPIO support 2010-03-16 6:41 ` [RFC/PATCH 05/10] [ARM] tegra: Add timer support konkers at google.com @ 2010-03-16 6:41 ` konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 07/10] [ARM] tegra: add pinmux support konkers at google.com 2010-03-17 8:15 ` [RFC/PATCH 06/10] [ARM] tegra: add GPIO support Mike Rapoport 0 siblings, 2 replies; 37+ messages in thread From: konkers at google.com @ 2010-03-16 6:41 UTC (permalink / raw) To: linux-arm-kernel From: Erik Gilling <konkers@android.com> Signed-off-by: Erik Gilling <konkers@android.com> Signed-off-by: Colin Cross <ccross@android.com> Cc: Gary King <gking@nvidia.com> --- arch/arm/mach-tegra/Kconfig | 1 + arch/arm/mach-tegra/Makefile | 1 + arch/arm/mach-tegra/gpio.c | 348 +++++++++++++++++++++++++ arch/arm/mach-tegra/include/mach/gpio-names.h | 247 ++++++++++++++++++ arch/arm/mach-tegra/include/mach/gpio.h | 51 ++++ 5 files changed, 648 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-tegra/gpio.c create mode 100644 arch/arm/mach-tegra/include/mach/gpio-names.h create mode 100644 arch/arm/mach-tegra/include/mach/gpio.h diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 64ab14f..1ec54d6 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -9,6 +9,7 @@ config ARCH_TEGRA_2x_SOC bool "Tegra 2 family" select CPU_V7 select ARM_GIC + select ARCH_REQUIRE_GPIOLIB help Support for NVIDIA Tegra AP20 and T20 processors, based on the ARM CortexA9MP CPU and the ARM PL310 L2 cache controller diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 01f47fd..122f7dc 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -3,6 +3,7 @@ obj-y += io.o obj-y += irq.o obj-y += clock.o obj-y += timer.o +obj-y += gpio.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c new file mode 100644 index 0000000..4820e01 --- /dev/null +++ b/arch/arm/mach-tegra/gpio.c @@ -0,0 +1,348 @@ +/* + * arch/arm/mach-tegra/gpio.c + * + * Copyright (c) 2010 Google, Inc + * + * Author: + * Erik Gilling <konkers@google.com> + * + * 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. + * + */ + +#include <linux/init.h> +#include <linux/irq.h> + +#include <asm/io.h> +#include <asm/gpio.h> + +#include <mach/iomap.h> + +#define GPIO_BANK(x) ((x) >> 5) +#define GPIO_PORT(x) (((x) >> 3) & 0x3) +#define GPIO_BIT(x) ((x) & 0x7) + +#define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \ + GPIO_BANK(x) * 0x80 + \ + GPIO_PORT(x) * 4) + +#define GPIO_CNF(x) (GPIO_REG(x) + 0x00) +#define GPIO_OE(x) (GPIO_REG(x) + 0x10) +#define GPIO_OUT(x) (GPIO_REG(x) + 0X20) +#define GPIO_IN(x) (GPIO_REG(x) + 0x30) +#define GPIO_INT_STA(x) (GPIO_REG(x) + 0x40) +#define GPIO_INT_ENB(x) (GPIO_REG(x) + 0x50) +#define GPIO_INT_LVL(x) (GPIO_REG(x) + 0x60) +#define GPIO_INT_CLR(x) (GPIO_REG(x) + 0x70) + +#define GPIO_MSK_CNF(x) (GPIO_REG(x) + 0x800) +#define GPIO_MSK_OE(x) (GPIO_REG(x) + 0x810) +#define GPIO_MSK_OUT(x) (GPIO_REG(x) + 0X820) +#define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + 0x840) +#define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + 0x850) +#define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + 0x860) + +#define GPIO_INT_LVL_MASK 0x010101 +#define GPIO_INT_LVL_EDGE_RISING 0x000101 +#define GPIO_INT_LVL_EDGE_FALLING 0x000100 +#define GPIO_INT_LVL_EDGE_BOTH 0x010100 +#define GPIO_INT_LVL_LEVEL_HIGH 0x000001 +#define GPIO_INT_LVL_LEVEL_LOW 0x000000 + +struct tegra_gpio_bank { + int bank; + int irq; + spinlock_t lvl_lock[4]; +}; + + +static struct tegra_gpio_bank tegra_gpio_banks[] = { + {.bank = 0, .irq = INT_GPIO1}, + {.bank = 1, .irq = INT_GPIO2}, + {.bank = 2, .irq = INT_GPIO3}, + {.bank = 3, .irq = INT_GPIO4}, + {.bank = 4, .irq = INT_GPIO5}, + {.bank = 5, .irq = INT_GPIO6}, + {.bank = 6, .irq = INT_GPIO7}, +}; + +static int tegra_gpio_compose(int bank, int port, int bit) +{ + return (bank << 5) | ((port & 0x3) << 3) | (bit & 0x7); +} + +static void tegra_gpio_mask_write(u32 reg, int gpio, int value) +{ + u32 val; + + val = 0x100 << GPIO_BIT(gpio); + if (value) + val |= 1 << GPIO_BIT(gpio); + __raw_writel(val, reg); +} + +void tegra_gpio_enable(int gpio) +{ + tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1); +} + +void tegra_gpio_disable(int gpio) +{ + tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0); +} + +static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + tegra_gpio_mask_write(GPIO_MSK_OUT(offset), offset, value); +} + +static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + return (__raw_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1; +} + +static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +{ + tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 0); + return 0; +} + +static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset, + int value) +{ + tegra_gpio_set(chip, offset, value); + tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 1); + return 0; +} + + + +static struct gpio_chip tegra_gpio_chip = { + .label = "tegra-gpio", + .direction_input = tegra_gpio_direction_input, + .get = tegra_gpio_get, + .direction_output = tegra_gpio_direction_output, + .set = tegra_gpio_set, + .base = 0, + .ngpio = ARCH_NR_GPIOS, +}; + +static void tegra_gpio_irq_ack(unsigned int irq) +{ + int gpio = irq - INT_GPIO_BASE; + + __raw_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio)); +} + +static void tegra_gpio_irq_mask(unsigned int irq) +{ + int gpio = irq - INT_GPIO_BASE; + + tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0); +} + +static void tegra_gpio_irq_unmask(unsigned int irq) +{ + int gpio = irq - INT_GPIO_BASE; + + tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1); +} + +static int tegra_gpio_irq_set_type(unsigned int irq, unsigned int type) +{ + int gpio = irq - INT_GPIO_BASE; + struct tegra_gpio_bank *bank = get_irq_chip_data(irq); + int port = GPIO_PORT(gpio); + int lvl_type; + int val; + unsigned long flags; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + lvl_type = GPIO_INT_LVL_EDGE_RISING; + break; + + case IRQ_TYPE_EDGE_FALLING: + lvl_type = GPIO_INT_LVL_EDGE_FALLING; + break; + + case IRQ_TYPE_EDGE_BOTH: + lvl_type = GPIO_INT_LVL_EDGE_BOTH; + break; + + case IRQ_TYPE_LEVEL_HIGH: + lvl_type = GPIO_INT_LVL_LEVEL_HIGH; + break; + + case IRQ_TYPE_LEVEL_LOW: + lvl_type = GPIO_INT_LVL_LEVEL_LOW; + break; + + default: + return -EINVAL; + } + + spin_lock_irqsave(&bank->lvl_lock[port], flags); + + val = __raw_readl(GPIO_INT_LVL(gpio)); + val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio)); + val |= lvl_type << GPIO_BIT(gpio); + __raw_writel(val, GPIO_INT_LVL(gpio)); + + spin_unlock_irqrestore(&bank->lvl_lock[port], flags); + + if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) + __set_irq_handler_unlocked(irq, handle_level_irq); + else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) + __set_irq_handler_unlocked(irq, handle_edge_irq); + + return 0; +} + +static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + struct tegra_gpio_bank *bank; + int port; + int pin; + int unmasked = 0; + + desc->chip->ack(irq); + + bank = get_irq_data(irq); + + for (port = 0; port < 4; port++) { + int gpio = tegra_gpio_compose(bank->bank, port, 0); + unsigned long sta = __raw_readl(GPIO_INT_STA(gpio)) & + __raw_readl(GPIO_INT_ENB(gpio)); + u32 lvl = __raw_readl(GPIO_INT_LVL(gpio)); + + for_each_bit(pin, &sta, 8) { + __raw_writel(1 << pin, GPIO_INT_CLR(gpio)); + + /* if gpio is edge triggered, clear condition + * before executing the hander so that we don't + * miss edges + */ + if (lvl & (0x100 << pin)) { + unmasked = 1; + desc->chip->unmask(irq); + } + + generic_handle_irq(gpio_to_irq(gpio + pin)); + } + } + + if (!unmasked) + desc->chip->unmask(irq); + +} + + +static struct irq_chip tegra_gpio_irq_chip = { + .name = "GPIO", + .ack = tegra_gpio_irq_ack, + .mask = tegra_gpio_irq_mask, + .unmask = tegra_gpio_irq_unmask, + .set_type = tegra_gpio_irq_set_type, +}; + + +/* This lock class tells lockdep that GPIO irqs are in a different + * category than their parents, so it won't report false recursion. + */ +static struct lock_class_key gpio_lock_class; + +static int __init tegra_gpio_init(void) +{ + struct tegra_gpio_bank *bank; + int i; + int j; + + for (i = 0; i < 7; i++) { + for (j = 0; j < 4; j++) { + int gpio = tegra_gpio_compose(i, j, 0); + __raw_writel(0x00, GPIO_INT_ENB(gpio)); + } + } + + gpiochip_add(&tegra_gpio_chip); + + for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + ARCH_NR_GPIOS); i++) { + bank = &tegra_gpio_banks[GPIO_BANK(irq_to_gpio(i))]; + + lockdep_set_class(&irq_desc[i].lock, &gpio_lock_class); + set_irq_chip_data(i, bank); + set_irq_chip(i, &tegra_gpio_irq_chip); + set_irq_handler(i, handle_simple_irq); + set_irq_flags(i, IRQF_VALID); + } + + for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { + bank = &tegra_gpio_banks[i]; + + set_irq_chained_handler(bank->irq, tegra_gpio_irq_handler); + set_irq_data(bank->irq, bank); + + for (j = 0; j < 4; j++) + spin_lock_init(&bank->lvl_lock[j]); + } + + return 0; +} + +postcore_initcall(tegra_gpio_init); + +#ifdef CONFIG_DEBUG_FS + +#include <linux/debugfs.h> +#include <linux/seq_file.h> + +static int dbg_gpio_show(struct seq_file *s, void *unused) +{ + int i; + int j; + + for (i = 0; i < 7; i++) { + for (j = 0; j < 4; j++) { + int gpio = tegra_gpio_compose(i, j, 0); + seq_printf(s, "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", + i, j, + __raw_readl(GPIO_CNF(gpio)), + __raw_readl(GPIO_OE(gpio)), + __raw_readl(GPIO_OUT(gpio)), + __raw_readl(GPIO_IN(gpio)), + __raw_readl(GPIO_INT_STA(gpio)), + __raw_readl(GPIO_INT_ENB(gpio)), + __raw_readl(GPIO_INT_LVL(gpio))); + } + } + return 0; +} + +static int dbg_gpio_open(struct inode *inode, struct file *file) +{ + return single_open(file, dbg_gpio_show, &inode->i_private); +} + +static const struct file_operations debug_fops = { + .open = dbg_gpio_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init tegra_gpio_debuginit(void) +{ + (void) debugfs_create_file("tegra_gpio", S_IRUGO, + NULL, NULL, &debug_fops); + return 0; +} +late_initcall(tegra_gpio_debuginit); +#endif diff --git a/arch/arm/mach-tegra/include/mach/gpio-names.h b/arch/arm/mach-tegra/include/mach/gpio-names.h new file mode 100644 index 0000000..f28220a --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/gpio-names.h @@ -0,0 +1,247 @@ +/* + * arch/arm/mach-tegra/include/mach/gpio-names.h + * + * Copyright (c) 2010 Google, Inc + * + * Author: + * Erik Gilling <konkers@google.com> + * + * 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. + */ + +#ifndef __MACH_TEGRA_GPIO_NAMES_H +#define __MACH_TEGRA_GPIO_NAMES_H + +#define TEGRA_GPIO_PA0 0 +#define TEGRA_GPIO_PA1 1 +#define TEGRA_GPIO_PA2 2 +#define TEGRA_GPIO_PA3 3 +#define TEGRA_GPIO_PA4 4 +#define TEGRA_GPIO_PA5 5 +#define TEGRA_GPIO_PA6 6 +#define TEGRA_GPIO_PA7 7 +#define TEGRA_GPIO_PB0 8 +#define TEGRA_GPIO_PB1 9 +#define TEGRA_GPIO_PB2 10 +#define TEGRA_GPIO_PB3 11 +#define TEGRA_GPIO_PB4 12 +#define TEGRA_GPIO_PB5 13 +#define TEGRA_GPIO_PB6 14 +#define TEGRA_GPIO_PB7 15 +#define TEGRA_GPIO_PC0 16 +#define TEGRA_GPIO_PC1 17 +#define TEGRA_GPIO_PC2 18 +#define TEGRA_GPIO_PC3 19 +#define TEGRA_GPIO_PC4 20 +#define TEGRA_GPIO_PC5 21 +#define TEGRA_GPIO_PC6 22 +#define TEGRA_GPIO_PC7 23 +#define TEGRA_GPIO_PD0 24 +#define TEGRA_GPIO_PD1 25 +#define TEGRA_GPIO_PD2 26 +#define TEGRA_GPIO_PD3 27 +#define TEGRA_GPIO_PD4 28 +#define TEGRA_GPIO_PD5 29 +#define TEGRA_GPIO_PD6 30 +#define TEGRA_GPIO_PD7 31 +#define TEGRA_GPIO_PE0 32 +#define TEGRA_GPIO_PE1 33 +#define TEGRA_GPIO_PE2 34 +#define TEGRA_GPIO_PE3 35 +#define TEGRA_GPIO_PE4 36 +#define TEGRA_GPIO_PE5 37 +#define TEGRA_GPIO_PE6 38 +#define TEGRA_GPIO_PE7 39 +#define TEGRA_GPIO_PF0 40 +#define TEGRA_GPIO_PF1 41 +#define TEGRA_GPIO_PF2 42 +#define TEGRA_GPIO_PF3 43 +#define TEGRA_GPIO_PF4 44 +#define TEGRA_GPIO_PF5 45 +#define TEGRA_GPIO_PF6 46 +#define TEGRA_GPIO_PF7 47 +#define TEGRA_GPIO_PG0 48 +#define TEGRA_GPIO_PG1 49 +#define TEGRA_GPIO_PG2 50 +#define TEGRA_GPIO_PG3 51 +#define TEGRA_GPIO_PG4 52 +#define TEGRA_GPIO_PG5 53 +#define TEGRA_GPIO_PG6 54 +#define TEGRA_GPIO_PG7 55 +#define TEGRA_GPIO_PH0 56 +#define TEGRA_GPIO_PH1 57 +#define TEGRA_GPIO_PH2 58 +#define TEGRA_GPIO_PH3 59 +#define TEGRA_GPIO_PH4 60 +#define TEGRA_GPIO_PH5 61 +#define TEGRA_GPIO_PH6 62 +#define TEGRA_GPIO_PH7 63 +#define TEGRA_GPIO_PI0 64 +#define TEGRA_GPIO_PI1 65 +#define TEGRA_GPIO_PI2 66 +#define TEGRA_GPIO_PI3 67 +#define TEGRA_GPIO_PI4 68 +#define TEGRA_GPIO_PI5 69 +#define TEGRA_GPIO_PI6 70 +#define TEGRA_GPIO_PI7 71 +#define TEGRA_GPIO_PJ0 72 +#define TEGRA_GPIO_PJ1 73 +#define TEGRA_GPIO_PJ2 74 +#define TEGRA_GPIO_PJ3 75 +#define TEGRA_GPIO_PJ4 76 +#define TEGRA_GPIO_PJ5 77 +#define TEGRA_GPIO_PJ6 78 +#define TEGRA_GPIO_PJ7 79 +#define TEGRA_GPIO_PK0 80 +#define TEGRA_GPIO_PK1 81 +#define TEGRA_GPIO_PK2 82 +#define TEGRA_GPIO_PK3 83 +#define TEGRA_GPIO_PK4 84 +#define TEGRA_GPIO_PK5 85 +#define TEGRA_GPIO_PK6 86 +#define TEGRA_GPIO_PK7 87 +#define TEGRA_GPIO_PL0 88 +#define TEGRA_GPIO_PL1 89 +#define TEGRA_GPIO_PL2 90 +#define TEGRA_GPIO_PL3 91 +#define TEGRA_GPIO_PL4 92 +#define TEGRA_GPIO_PL5 93 +#define TEGRA_GPIO_PL6 94 +#define TEGRA_GPIO_PL7 95 +#define TEGRA_GPIO_PM0 96 +#define TEGRA_GPIO_PM1 97 +#define TEGRA_GPIO_PM2 98 +#define TEGRA_GPIO_PM3 99 +#define TEGRA_GPIO_PM4 100 +#define TEGRA_GPIO_PM5 101 +#define TEGRA_GPIO_PM6 102 +#define TEGRA_GPIO_PM7 103 +#define TEGRA_GPIO_PN0 104 +#define TEGRA_GPIO_PN1 105 +#define TEGRA_GPIO_PN2 106 +#define TEGRA_GPIO_PN3 107 +#define TEGRA_GPIO_PN4 108 +#define TEGRA_GPIO_PN5 109 +#define TEGRA_GPIO_PN6 110 +#define TEGRA_GPIO_PN7 111 +#define TEGRA_GPIO_PO0 112 +#define TEGRA_GPIO_PO1 113 +#define TEGRA_GPIO_PO2 114 +#define TEGRA_GPIO_PO3 115 +#define TEGRA_GPIO_PO4 116 +#define TEGRA_GPIO_PO5 117 +#define TEGRA_GPIO_PO6 118 +#define TEGRA_GPIO_PO7 119 +#define TEGRA_GPIO_PP0 120 +#define TEGRA_GPIO_PP1 121 +#define TEGRA_GPIO_PP2 122 +#define TEGRA_GPIO_PP3 123 +#define TEGRA_GPIO_PP4 124 +#define TEGRA_GPIO_PP5 125 +#define TEGRA_GPIO_PP6 126 +#define TEGRA_GPIO_PP7 127 +#define TEGRA_GPIO_PQ0 128 +#define TEGRA_GPIO_PQ1 129 +#define TEGRA_GPIO_PQ2 130 +#define TEGRA_GPIO_PQ3 131 +#define TEGRA_GPIO_PQ4 132 +#define TEGRA_GPIO_PQ5 133 +#define TEGRA_GPIO_PQ6 134 +#define TEGRA_GPIO_PQ7 135 +#define TEGRA_GPIO_PR0 136 +#define TEGRA_GPIO_PR1 137 +#define TEGRA_GPIO_PR2 138 +#define TEGRA_GPIO_PR3 139 +#define TEGRA_GPIO_PR4 140 +#define TEGRA_GPIO_PR5 141 +#define TEGRA_GPIO_PR6 142 +#define TEGRA_GPIO_PR7 143 +#define TEGRA_GPIO_PS0 144 +#define TEGRA_GPIO_PS1 145 +#define TEGRA_GPIO_PS2 146 +#define TEGRA_GPIO_PS3 147 +#define TEGRA_GPIO_PS4 148 +#define TEGRA_GPIO_PS5 149 +#define TEGRA_GPIO_PS6 150 +#define TEGRA_GPIO_PS7 151 +#define TEGRA_GPIO_PT0 152 +#define TEGRA_GPIO_PT1 153 +#define TEGRA_GPIO_PT2 154 +#define TEGRA_GPIO_PT3 155 +#define TEGRA_GPIO_PT4 156 +#define TEGRA_GPIO_PT5 157 +#define TEGRA_GPIO_PT6 158 +#define TEGRA_GPIO_PT7 159 +#define TEGRA_GPIO_PU0 160 +#define TEGRA_GPIO_PU1 161 +#define TEGRA_GPIO_PU2 162 +#define TEGRA_GPIO_PU3 163 +#define TEGRA_GPIO_PU4 164 +#define TEGRA_GPIO_PU5 165 +#define TEGRA_GPIO_PU6 166 +#define TEGRA_GPIO_PU7 167 +#define TEGRA_GPIO_PV0 168 +#define TEGRA_GPIO_PV1 169 +#define TEGRA_GPIO_PV2 170 +#define TEGRA_GPIO_PV3 171 +#define TEGRA_GPIO_PV4 172 +#define TEGRA_GPIO_PV5 173 +#define TEGRA_GPIO_PV6 174 +#define TEGRA_GPIO_PV7 175 +#define TEGRA_GPIO_PW0 176 +#define TEGRA_GPIO_PW1 177 +#define TEGRA_GPIO_PW2 178 +#define TEGRA_GPIO_PW3 179 +#define TEGRA_GPIO_PW4 180 +#define TEGRA_GPIO_PW5 181 +#define TEGRA_GPIO_PW6 182 +#define TEGRA_GPIO_PW7 183 +#define TEGRA_GPIO_PX0 184 +#define TEGRA_GPIO_PX1 185 +#define TEGRA_GPIO_PX2 186 +#define TEGRA_GPIO_PX3 187 +#define TEGRA_GPIO_PX4 188 +#define TEGRA_GPIO_PX5 189 +#define TEGRA_GPIO_PX6 190 +#define TEGRA_GPIO_PX7 191 +#define TEGRA_GPIO_PY0 192 +#define TEGRA_GPIO_PY1 193 +#define TEGRA_GPIO_PY2 194 +#define TEGRA_GPIO_PY3 195 +#define TEGRA_GPIO_PY4 196 +#define TEGRA_GPIO_PY5 197 +#define TEGRA_GPIO_PY6 198 +#define TEGRA_GPIO_PY7 199 +#define TEGRA_GPIO_PZ0 200 +#define TEGRA_GPIO_PZ1 201 +#define TEGRA_GPIO_PZ2 202 +#define TEGRA_GPIO_PZ3 203 +#define TEGRA_GPIO_PZ4 204 +#define TEGRA_GPIO_PZ5 205 +#define TEGRA_GPIO_PZ6 206 +#define TEGRA_GPIO_PZ7 207 +#define TEGRA_GPIO_PAA0 208 +#define TEGRA_GPIO_PAA1 209 +#define TEGRA_GPIO_PAA2 210 +#define TEGRA_GPIO_PAA3 211 +#define TEGRA_GPIO_PAA4 212 +#define TEGRA_GPIO_PAA5 213 +#define TEGRA_GPIO_PAA6 214 +#define TEGRA_GPIO_PAA7 215 +#define TEGRA_GPIO_PBB0 216 +#define TEGRA_GPIO_PBB1 217 +#define TEGRA_GPIO_PBB2 218 +#define TEGRA_GPIO_PBB3 219 +#define TEGRA_GPIO_PBB4 220 +#define TEGRA_GPIO_PBB5 221 +#define TEGRA_GPIO_PBB6 222 +#define TEGRA_GPIO_PBB7 223 + +#endif diff --git a/arch/arm/mach-tegra/include/mach/gpio.h b/arch/arm/mach-tegra/include/mach/gpio.h new file mode 100644 index 0000000..871cd10 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/gpio.h @@ -0,0 +1,51 @@ +/* + * arch/arm/mach-tegra/include/mach/gpio.h + * + * Copyright (C) 2010 Google, Inc. + * + * Author: + * Erik Gilling <konkers@google.com> + * + * 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. + * + */ + +#ifndef __MACH_TEGRA_GPIO_H +#define __MACH_TEGRA_GPIO_H + +#include <mach/irqs.h> + +#define ARCH_NR_GPIOS INT_GPIO_NR + +#include <asm-generic/gpio.h> +#include <mach/gpio-names.h> + +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value +#define gpio_cansleep __gpio_cansleep + +static inline int gpio_to_irq(unsigned int gpio) +{ + if (gpio < ARCH_NR_GPIOS) + return INT_GPIO_BASE + gpio; + return -EINVAL; +} + +static inline int irq_to_gpio(unsigned int irq) +{ + if ((irq >= INT_GPIO_BASE) && (irq < INT_GPIO_BASE + INT_GPIO_NR)) + return irq - INT_GPIO_BASE; + return -EINVAL; +} + +void tegra_gpio_enable(int gpio); +void tegra_gpio_disable(int gpio); + +#endif -- 1.6.5.6 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [RFC/PATCH 07/10] [ARM] tegra: add pinmux support 2010-03-16 6:41 ` [RFC/PATCH 06/10] [ARM] tegra: add GPIO support konkers at google.com @ 2010-03-16 6:41 ` konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 08/10] [ARM] tegra: Add framebuffer driver konkers at google.com 2010-03-17 8:15 ` [RFC/PATCH 06/10] [ARM] tegra: add GPIO support Mike Rapoport 1 sibling, 1 reply; 37+ messages in thread From: konkers at google.com @ 2010-03-16 6:41 UTC (permalink / raw) To: linux-arm-kernel From: Erik Gilling <konkers@android.com> Signed-off-by: Erik Gilling <konkers@android.com> Signed-off-by: Colin Cross <ccross@android.com> --- arch/arm/mach-tegra/Makefile | 2 + arch/arm/mach-tegra/include/mach/pinmux.h | 241 +++++++++++++ arch/arm/mach-tegra/pinmux.c | 548 +++++++++++++++++++++++++++++ 3 files changed, 791 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-tegra/include/mach/pinmux.h create mode 100644 arch/arm/mach-tegra/pinmux.c diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 122f7dc..5e47a71 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -4,6 +4,8 @@ obj-y += irq.o obj-y += clock.o obj-y += timer.o obj-y += gpio.o +obj-y += pinmux.o +obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/arch/arm/mach-tegra/include/mach/pinmux.h b/arch/arm/mach-tegra/include/mach/pinmux.h new file mode 100644 index 0000000..02a706b --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/pinmux.h @@ -0,0 +1,241 @@ +/* + * linux/arch/arm/mach-tegra/include/mach/pinmux.h + * + * Copyright (C) 2010 Google, Inc. + * + * 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. + * + */ + +#ifndef __MACH_TEGRA_PINMUX_H +#define __MACH_TEGRA_PINMUX_H + +typedef enum { + TEGRA_PINGROUP_ATA = 0, + TEGRA_PINGROUP_ATB, + TEGRA_PINGROUP_ATC, + TEGRA_PINGROUP_ATD, + TEGRA_PINGROUP_ATE, + TEGRA_PINGROUP_CDEV1, + TEGRA_PINGROUP_CDEV2, + TEGRA_PINGROUP_CRTP, + TEGRA_PINGROUP_CSUS, + TEGRA_PINGROUP_DAP1, + TEGRA_PINGROUP_DAP2, + TEGRA_PINGROUP_DAP3, + TEGRA_PINGROUP_DAP4, + TEGRA_PINGROUP_DDC, + TEGRA_PINGROUP_DTA, + TEGRA_PINGROUP_DTB, + TEGRA_PINGROUP_DTC, + TEGRA_PINGROUP_DTD, + TEGRA_PINGROUP_DTE, + TEGRA_PINGROUP_DTF, + TEGRA_PINGROUP_GMA, + TEGRA_PINGROUP_GMB, + TEGRA_PINGROUP_GMC, + TEGRA_PINGROUP_GMD, + TEGRA_PINGROUP_GME, + TEGRA_PINGROUP_GPU, + TEGRA_PINGROUP_GPU7, + TEGRA_PINGROUP_GPV, + TEGRA_PINGROUP_HDINT, + TEGRA_PINGROUP_I2CP, + TEGRA_PINGROUP_IRRX, + TEGRA_PINGROUP_IRTX, + TEGRA_PINGROUP_KBCA, + TEGRA_PINGROUP_KBCB, + TEGRA_PINGROUP_KBCC, + TEGRA_PINGROUP_KBCD, + TEGRA_PINGROUP_KBCE, + TEGRA_PINGROUP_KBCF, + TEGRA_PINGROUP_LCSN, + TEGRA_PINGROUP_LD0, + TEGRA_PINGROUP_LD1, + TEGRA_PINGROUP_LD10, + TEGRA_PINGROUP_LD11, + TEGRA_PINGROUP_LD12, + TEGRA_PINGROUP_LD13, + TEGRA_PINGROUP_LD14, + TEGRA_PINGROUP_LD15, + TEGRA_PINGROUP_LD16, + TEGRA_PINGROUP_LD17, + TEGRA_PINGROUP_LD2, + TEGRA_PINGROUP_LD3, + TEGRA_PINGROUP_LD4, + TEGRA_PINGROUP_LD5, + TEGRA_PINGROUP_LD6, + TEGRA_PINGROUP_LD7, + TEGRA_PINGROUP_LD8, + TEGRA_PINGROUP_LD9, + TEGRA_PINGROUP_LDC, + TEGRA_PINGROUP_LDI, + TEGRA_PINGROUP_LHP0, + TEGRA_PINGROUP_LHP1, + TEGRA_PINGROUP_LHP2, + TEGRA_PINGROUP_LHS, + TEGRA_PINGROUP_LM0, + TEGRA_PINGROUP_LM1, + TEGRA_PINGROUP_LPP, + TEGRA_PINGROUP_LPW0, + TEGRA_PINGROUP_LPW1, + TEGRA_PINGROUP_LPW2, + TEGRA_PINGROUP_LSC0, + TEGRA_PINGROUP_LSC1, + TEGRA_PINGROUP_LSCK, + TEGRA_PINGROUP_LSDA, + TEGRA_PINGROUP_LSDI, + TEGRA_PINGROUP_LSPI, + TEGRA_PINGROUP_LVP0, + TEGRA_PINGROUP_LVP1, + TEGRA_PINGROUP_LVS, + TEGRA_PINGROUP_OWC, + TEGRA_PINGROUP_PMC, + TEGRA_PINGROUP_PTA, + TEGRA_PINGROUP_RM, + TEGRA_PINGROUP_SDB, + TEGRA_PINGROUP_SDC, + TEGRA_PINGROUP_SDD, + TEGRA_PINGROUP_SDIO1, + TEGRA_PINGROUP_SLXA, + TEGRA_PINGROUP_SLXC, + TEGRA_PINGROUP_SLXD, + TEGRA_PINGROUP_SLXK, + TEGRA_PINGROUP_SPDI, + TEGRA_PINGROUP_SPDO, + TEGRA_PINGROUP_SPIA, + TEGRA_PINGROUP_SPIB, + TEGRA_PINGROUP_SPIC, + TEGRA_PINGROUP_SPID, + TEGRA_PINGROUP_SPIE, + TEGRA_PINGROUP_SPIF, + TEGRA_PINGROUP_SPIG, + TEGRA_PINGROUP_SPIH, + TEGRA_PINGROUP_UAA, + TEGRA_PINGROUP_UAB, + TEGRA_PINGROUP_UAC, + TEGRA_PINGROUP_UAD, + TEGRA_PINGROUP_UCA, + TEGRA_PINGROUP_UCB, + TEGRA_PINGROUP_UDA, + /* these pin groups only have pullup and pull down control */ + TEGRA_PINGROUP_CK32, + TEGRA_PINGROUP_DDRC, + TEGRA_PINGROUP_PMCA, + TEGRA_PINGROUP_PMCB, + TEGRA_PINGROUP_PMCC, + TEGRA_PINGROUP_PMCD, + TEGRA_PINGROUP_PMCE, + TEGRA_PINGROUP_XM2C, + TEGRA_PINGROUP_XM2D, + TEGRA_MAX_PINGROUP, +} tegra_pingroup_t; + +typedef enum { + TEGRA_MUX_RSVD = 0x8000, + TEGRA_MUX_RSVD1 = 0x8000, + TEGRA_MUX_RSVD2 = 0x8001, + TEGRA_MUX_RSVD3 = 0x8002, + TEGRA_MUX_RSVD4 = 0x8003, + TEGRA_MUX_NONE = -1, + TEGRA_MUX_AHB_CLK, + TEGRA_MUX_APB_CLK, + TEGRA_MUX_AUDIO_SYNC, + TEGRA_MUX_CRT, + TEGRA_MUX_DAP1, + TEGRA_MUX_DAP2, + TEGRA_MUX_DAP3, + TEGRA_MUX_DAP4, + TEGRA_MUX_DAP5, + TEGRA_MUX_DISPLAYA, + TEGRA_MUX_DISPLAYB, + TEGRA_MUX_EMC_TEST0_DLL, + TEGRA_MUX_EMC_TEST1_DLL, + TEGRA_MUX_GMI, + TEGRA_MUX_GMI_INT, + TEGRA_MUX_HDMI, + TEGRA_MUX_I2C, + TEGRA_MUX_I2C2, + TEGRA_MUX_I2C3, + TEGRA_MUX_IDE, + TEGRA_MUX_IRDA, + TEGRA_MUX_KBC, + TEGRA_MUX_MIO, + TEGRA_MUX_MIPI_HS, + TEGRA_MUX_NAND, + TEGRA_MUX_OSC, + TEGRA_MUX_OWR, + TEGRA_MUX_PCIE, + TEGRA_MUX_PLLA_OUT, + TEGRA_MUX_PLLC_OUT1, + TEGRA_MUX_PLLM_OUT1, + TEGRA_MUX_PLLP_OUT2, + TEGRA_MUX_PLLP_OUT3, + TEGRA_MUX_PLLP_OUT4, + TEGRA_MUX_PWM, + TEGRA_MUX_PWR_INTR, + TEGRA_MUX_PWR_ON, + TEGRA_MUX_RTCK, + TEGRA_MUX_SDIO1, + TEGRA_MUX_SDIO2, + TEGRA_MUX_SDIO3, + TEGRA_MUX_SDIO4, + TEGRA_MUX_SFLASH, + TEGRA_MUX_SPDIF, + TEGRA_MUX_SPI1, + TEGRA_MUX_SPI2, + TEGRA_MUX_SPI2_ALT, + TEGRA_MUX_SPI3, + TEGRA_MUX_SPI4, + TEGRA_MUX_TRACE, + TEGRA_MUX_TWC, + TEGRA_MUX_UARTA, + TEGRA_MUX_UARTB, + TEGRA_MUX_UARTC, + TEGRA_MUX_UARTD, + TEGRA_MUX_UARTE, + TEGRA_MUX_ULPI, + TEGRA_MUX_VI, + TEGRA_MUX_VI_SENSOR_CLK, + TEGRA_MUX_XIO, + TEGRA_MAX_MUX, +} tegra_mux_func_t; + +typedef enum { + TEGRA_PUPD_NORMAL = 0, + TEGRA_PUPD_PULL_DOWN, + TEGRA_PUPD_PULL_UP, +} tegra_pullupdown_t; + +typedef enum { + TEGRA_TRI_NORMAL = 0, + TEGRA_TRI_TRISTATE = 1, +} tegra_tristate_t; + +struct tegra_pingroup_config { + tegra_pingroup_t pingroup; + tegra_mux_func_t func; + tegra_pullupdown_t pupd; + tegra_tristate_t tristate; +}; + +int tegra_pinmux_set_func(tegra_pingroup_t pg, tegra_mux_func_t func); +int tegra_pinmux_set_tristate(tegra_pingroup_t pg, tegra_tristate_t tristate); +int tegra_pinmux_set_pullupdown(tegra_pingroup_t pg, tegra_pullupdown_t pupd); + +void tegra_pinmux_config_pingroup(tegra_pingroup_t pingroup, + tegra_mux_func_t func, + tegra_pullupdown_t pupd, + tegra_tristate_t tristate); + +void tegra_pinmux_config_table(struct tegra_pingroup_config *config, int len); + +#endif + diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c new file mode 100644 index 0000000..34ee94c --- /dev/null +++ b/arch/arm/mach-tegra/pinmux.c @@ -0,0 +1,548 @@ +/* + * linux/arch/arm/mach-tegra/pinmux.c + * + * Copyright (C) 2010 Google, Inc. + * + * 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. + * + */ + + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/spinlock.h> +#include <asm/io.h> + +#include <mach/iomap.h> +#include <mach/pinmux.h> + + +#define TEGRA_TRI_STATE(x) (0x14 + (4 * (x))) +#define TEGRA_PP_MUX_CTL(x) (0x80 + (4 * (x))) +#define TEGRA_PP_PU_PD(x) (0xa0 + (4 * (x))) + +#define REG_A 0 +#define REG_B 1 +#define REG_C 2 +#define REG_D 3 +#define REG_E 4 +#define REG_F 5 +#define REG_G 6 + +#define REG_N -1 + +struct tegra_pingroup_desc { + const char *name; + int funcs[4]; + s8 tri_reg; /* offset into the TRISTATE_REG_* register bank */ + s8 tri_bit; /* offset into the TRISTATE_REG_* register bit */ + s8 mux_reg; /* offset into the PIN_MUX_CTL_* register bank */ + s8 mux_bit; /* offset into the PIN_MUX_CTL_* register bit */ + s8 pupd_reg; /* offset into the PULL_UPDOWN_REG_* register bank */ + s8 pupd_bit; /* offset into the PULL_UPDOWN_REG_* register bit */ +}; + +#define PINGROUP(pg_name, f0, f1, f2, f3, \ + tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b) \ + [TEGRA_PINGROUP_ ## pg_name] = { \ + .name = #pg_name, \ + .funcs = { \ + TEGRA_MUX_ ## f0, \ + TEGRA_MUX_ ## f1, \ + TEGRA_MUX_ ## f2, \ + TEGRA_MUX_ ## f3, \ + }, \ + .tri_reg = REG_ ## tri_r, \ + .tri_bit = tri_b, \ + .mux_reg = REG_ ## mux_r, \ + .mux_bit = mux_b, \ + .pupd_reg = REG_ ## pupd_r, \ + .pupd_bit = pupd_b, \ + } + +static const struct tegra_pingroup_desc pingroups[TEGRA_MAX_PINGROUP] = { + PINGROUP(ATA, IDE, NAND, GMI, RSVD, A, 0, A, 24, A, 0), + PINGROUP(ATB, IDE, NAND, GMI, SDIO4, A, 1, A, 16, A, 2), + PINGROUP(ATC, IDE, NAND, GMI, SDIO4, A, 2, A, 22, A, 4), + PINGROUP(ATD, IDE, NAND, GMI, SDIO4, A, 3, A, 20, A, 6), + PINGROUP(ATE, IDE, NAND, GMI, RSVD, B, 25, A, 12, A, 8), + PINGROUP(CDEV1, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, A, 4, C, 2, C, 0), + PINGROUP(CDEV2, OSC, AHB_CLK, APB_CLK, PLLP_OUT4, A, 5, C, 4, C, 2), + PINGROUP(CRTP, CRT, RSVD, RSVD, RSVD, D, 14, G, 20, B, 24), + PINGROUP(CSUS, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, A, 6, C, 6, D, 24), + PINGROUP(DAP1, DAP1, RSVD, GMI, SDIO2, A, 7, C, 20, A, 10), + PINGROUP(DAP2, DAP2, TWC, RSVD, GMI, A, 8, C, 22, A, 12), + PINGROUP(DAP3, DAP3, RSVD, RSVD, RSVD, A, 9, C, 24, A, 14), + PINGROUP(DAP4, DAP4, RSVD, GMI, RSVD, A, 10, C, 26, A, 16), + PINGROUP(DDC, I2C2, RSVD, RSVD, RSVD, B, 31, C, 0, E, 28), + PINGROUP(DTA, RSVD, SDIO2, VI, RSVD, A, 11, B, 20, A, 18), + PINGROUP(DTB, RSVD, RSVD, VI, SPI1, A, 12, B, 22, A, 20), + PINGROUP(DTC, RSVD, RSVD, VI, RSVD, A, 13, B, 26, A, 22), + PINGROUP(DTD, RSVD, SDIO2, VI, RSVD, A, 14, B, 28, A, 24), + PINGROUP(DTE, RSVD, RSVD, VI, SPI1, A, 15, B, 30, A, 26), + PINGROUP(DTF, I2C3, RSVD, VI, RSVD, D, 12, G, 30, A, 28), + PINGROUP(GMA, UARTE, SPI3, GMI, SDIO4, A, 28, B, 0, E, 20), + PINGROUP(GMB, IDE, NAND, GMI, GMI_INT, B, 29, C, 28, E, 22), + PINGROUP(GMC, UARTD, SPI4, GMI, SFLASH, A, 29, B, 2, E, 24), + PINGROUP(GMD, RSVD, NAND, GMI, SFLASH, B, 30, C, 30, E, 26), + PINGROUP(GME, RSVD, DAP5, GMI, SDIO4, B, 0, D, 0, C, 24), + PINGROUP(GPU, PWM, UARTA, GMI, RSVD, A, 16, D, 4, B, 20), + PINGROUP(GPU7, RTCK, RSVD, RSVD, RSVD, D, 11, G, 28, B, 6), + PINGROUP(GPV, PCIE, RSVD, RSVD, RSVD, A, 17, D, 2, A, 30), + PINGROUP(HDINT, HDMI, RSVD, RSVD, RSVD, C, 23, B, 4, D, 22), + PINGROUP(I2CP, I2C, RSVD, RSVD, RSVD, A, 18, C, 8, B, 2), + PINGROUP(IRRX, UARTA, UARTB, GMI, SPI4, A, 20, C, 18, C, 22), + PINGROUP(IRTX, UARTA, UARTB, GMI, SPI4, A, 19, C, 16, C, 20), + PINGROUP(KBCA, KBC, NAND, SDIO2, EMC_TEST0_DLL, A, 22, C, 10, B, 8), + PINGROUP(KBCB, KBC, NAND, SDIO2, MIO, A, 21, C, 12, B, 10), + PINGROUP(KBCC, KBC, NAND, TRACE, EMC_TEST1_DLL, B, 26, C, 14, B, 12), + PINGROUP(KBCD, KBC, NAND, SDIO2, MIO, D, 10, G, 26, B, 14), + PINGROUP(KBCE, KBC, NAND, OWR, RSVD, A, 26, A, 28, E, 2), + PINGROUP(KBCF, KBC, NAND, TRACE, MIO, A, 27, A, 26, E, 0), + PINGROUP(LCSN, DISPLAYA, DISPLAYB, SPI3, RSVD, C, 31, E, 12, D, 20), + PINGROUP(LD0, DISPLAYA, DISPLAYB, XIO, RSVD, C, 0, F, 0, D, 12), + PINGROUP(LD1, DISPLAYA, DISPLAYB, XIO, RSVD, C, 1, F, 2, D, 12), + PINGROUP(LD10, DISPLAYA, DISPLAYB, XIO, RSVD, C, 10, F, 20, D, 12), + PINGROUP(LD11, DISPLAYA, DISPLAYB, XIO, RSVD, C, 11, F, 22, D, 12), + PINGROUP(LD12, DISPLAYA, DISPLAYB, XIO, RSVD, C, 12, F, 24, D, 12), + PINGROUP(LD13, DISPLAYA, DISPLAYB, XIO, RSVD, C, 13, F, 26, D, 12), + PINGROUP(LD14, DISPLAYA, DISPLAYB, XIO, RSVD, C, 14, F, 28, D, 12), + PINGROUP(LD15, DISPLAYA, DISPLAYB, XIO, RSVD, C, 15, F, 30, D, 12), + PINGROUP(LD16, DISPLAYA, DISPLAYB, XIO, RSVD, C, 16, G, 0, D, 12), + PINGROUP(LD17, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 17, G, 2, D, 12), + PINGROUP(LD2, DISPLAYA, DISPLAYB, XIO, RSVD, C, 2, F, 4, D, 12), + PINGROUP(LD3, DISPLAYA, DISPLAYB, XIO, RSVD, C, 3, F, 6, D, 12), + PINGROUP(LD4, DISPLAYA, DISPLAYB, XIO, RSVD, C, 4, F, 8, D, 12), + PINGROUP(LD5, DISPLAYA, DISPLAYB, XIO, RSVD, C, 5, F, 10, D, 12), + PINGROUP(LD6, DISPLAYA, DISPLAYB, XIO, RSVD, C, 6, F, 12, D, 12), + PINGROUP(LD7, DISPLAYA, DISPLAYB, XIO, RSVD, C, 7, F, 14, D, 12), + PINGROUP(LD8, DISPLAYA, DISPLAYB, XIO, RSVD, C, 8, F, 16, D, 12), + PINGROUP(LD9, DISPLAYA, DISPLAYB, XIO, RSVD, C, 9, F, 18, D, 12), + PINGROUP(LDC, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 30, E, 14, D, 20), + PINGROUP(LDI, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 6, G, 16, D, 18), + PINGROUP(LHP0, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 18, G, 10, D, 16), + PINGROUP(LHP1, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 19, G, 4, D, 14), + PINGROUP(LHP2, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 20, G, 6, D, 14), + PINGROUP(LHS, DISPLAYA, DISPLAYB, XIO, RSVD, D, 7, E, 22, D, 22), + PINGROUP(LM0, DISPLAYA, DISPLAYB, SPI3, RSVD, C, 24, E, 26, D, 22), + PINGROUP(LM1, DISPLAYA, DISPLAYB, RSVD, CRT, C, 25, E, 28, D, 22), + PINGROUP(LPP, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 8, G, 14, D, 18), + PINGROUP(LPW0, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 3, E, 0, D, 20), + PINGROUP(LPW1, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 4, E, 2, D, 20), + PINGROUP(LPW2, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 5, E, 4, D, 20), + PINGROUP(LSC0, DISPLAYA, DISPLAYB, XIO, RSVD, C, 27, E, 18, D, 22), + PINGROUP(LSC1, DISPLAYA, DISPLAYB, SPI3, HDMI, C, 28, E, 20, D, 20), + PINGROUP(LSCK, DISPLAYA, DISPLAYB, SPI3, HDMI, C, 29, E, 16, D, 20), + PINGROUP(LSDA, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 1, E, 8, D, 20), + PINGROUP(LSDI, DISPLAYA, DISPLAYB, SPI3, RSVD, D, 2, E, 6, D, 20), + PINGROUP(LSPI, DISPLAYA, DISPLAYB, XIO, HDMI, D, 0, E, 10, D, 22), + PINGROUP(LVP0, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 21, E, 30, D, 22), + PINGROUP(LVP1, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 22, G, 8, D, 16), + PINGROUP(LVS, DISPLAYA, DISPLAYB, XIO, RSVD, C, 26, E, 24, D, 22), + PINGROUP(OWC, OWR, RSVD, RSVD, RSVD, A, 31, B, 8, E, 30), + PINGROUP(PMC, PWR_ON, PWR_INTR, RSVD, RSVD, A, 23, G, 18, N, -1), + PINGROUP(PTA, I2C2, HDMI, GMI, RSVD, A, 24, G, 22, B, 4), + PINGROUP(RM, I2C, RSVD, RSVD, RSVD, A, 25, A, 14, B, 0), + PINGROUP(SDB, UARTA, PWM, SDIO3, SPI2, D, 15, D, 10, N, -1), + PINGROUP(SDC, PWM, TWC, SDIO3, SPI3, B, 1, D, 12, D, 28), + PINGROUP(SDD, UARTA, PWM, SDIO3, SPI3, B, 2, D, 14, D, 30), + PINGROUP(SDIO1, SDIO1, RSVD, UARTE, UARTA, A, 30, A, 30, E, 18), + PINGROUP(SLXA, PCIE, SPI4, SDIO3, SPI2, B, 3, B, 6, B, 22), + PINGROUP(SLXC, SPDIF, SPI4, SDIO3, SPI2, B, 5, B, 10, B, 26), + PINGROUP(SLXD, SPDIF, SPI4, SDIO3, SPI2, B, 6, B, 12, B, 28), + PINGROUP(SLXK, PCIE, SPI4, SDIO3, SPI2, B, 7, B, 14, B, 30), + PINGROUP(SPDI, SPDIF, RSVD, I2C, SDIO2, B, 8, D, 8, B, 16), + PINGROUP(SPDO, SPDIF, RSVD, I2C, SDIO2, B, 9, D, 6, B, 18), + PINGROUP(SPIA, SPI1, SPI2, SPI3, GMI, B, 10, D, 30, C, 4), + PINGROUP(SPIB, SPI1, SPI2, SPI3, GMI, B, 11, D, 28, C, 6), + PINGROUP(SPIC, SPI1, SPI2, SPI3, GMI, B, 12, D, 26, C, 8), + PINGROUP(SPID, SPI2, SPI1, SPI2_ALT, GMI, B, 13, D, 24, C, 10), + PINGROUP(SPIE, SPI2, SPI1, SPI2_ALT, GMI, B, 14, D, 22, C, 12), + PINGROUP(SPIF, SPI3, SPI1, SPI2, RSVD, B, 15, D, 20, C, 14), + PINGROUP(SPIG, SPI3, SPI2, SPI2_ALT, I2C, B, 16, D, 18, C, 16), + PINGROUP(SPIH, SPI3, SPI2, SPI2_ALT, I2C, B, 17, D, 16, C, 18), + PINGROUP(UAA, SPI3, MIPI_HS, UARTA, ULPI, B, 18, A, 0, D, 0), + PINGROUP(UAB, SPI2, MIPI_HS, UARTA, ULPI, B, 19, A, 2, D, 2), + PINGROUP(UAC, OWR, RSVD, RSVD, RSVD, B, 20, A, 4, D, 4), + PINGROUP(UAD, IRDA, SPDIF, UARTA, SPI4, B, 21, A, 6, D, 6), + PINGROUP(UCA, UARTC, RSVD, GMI, RSVD, B, 22, B, 16, D, 8), + PINGROUP(UCB, UARTC, PWM, GMI, RSVD, B, 23, B, 18, D, 10), + PINGROUP(UDA, SPI1, RSVD, UARTD, ULPI, D, 13, A, 8, E, 16), + /* these pin groups only have pullup and pull down control */ + PINGROUP(CK32, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 14), + PINGROUP(DDRC, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, D, 26), + PINGROUP(PMCA, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 4), + PINGROUP(PMCB, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 6), + PINGROUP(PMCC, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 8), + PINGROUP(PMCD, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 10), + PINGROUP(PMCE, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 12), + PINGROUP(XM2C, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, C, 30), + PINGROUP(XM2D, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, C, 28), +}; + +static char *tegra_mux_names[TEGRA_MAX_MUX] = { + [TEGRA_MUX_AHB_CLK] = "AHB_CLK", + [TEGRA_MUX_APB_CLK] = "APB_CLK", + [TEGRA_MUX_AUDIO_SYNC] = "AUDIO_SYNC", + [TEGRA_MUX_CRT] = "CRT", + [TEGRA_MUX_DAP1] = "DAP1", + [TEGRA_MUX_DAP2] = "DAP2", + [TEGRA_MUX_DAP3] = "DAP3", + [TEGRA_MUX_DAP4] = "DAP4", + [TEGRA_MUX_DAP5] = "DAP5", + [TEGRA_MUX_DISPLAYA] = "DISPLAYA", + [TEGRA_MUX_DISPLAYB] = "DISPLAYB", + [TEGRA_MUX_EMC_TEST0_DLL] = "EMC_TEST0_DLL", + [TEGRA_MUX_EMC_TEST1_DLL] = "EMC_TEST1_DLL", + [TEGRA_MUX_GMI] = "GMI", + [TEGRA_MUX_GMI_INT] = "GMI_INT", + [TEGRA_MUX_HDMI] = "HDMI", + [TEGRA_MUX_I2C] = "I2C", + [TEGRA_MUX_I2C2] = "I2C2", + [TEGRA_MUX_I2C3] = "I2C3", + [TEGRA_MUX_IDE] = "IDE", + [TEGRA_MUX_IRDA] = "IRDA", + [TEGRA_MUX_KBC] = "KBC", + [TEGRA_MUX_MIO] = "MIO", + [TEGRA_MUX_MIPI_HS] = "MIPI_HS", + [TEGRA_MUX_NAND] = "NAND", + [TEGRA_MUX_OSC] = "OSC", + [TEGRA_MUX_OWR] = "OWR", + [TEGRA_MUX_PCIE] = "PCIE", + [TEGRA_MUX_PLLA_OUT] = "PLLA_OUT", + [TEGRA_MUX_PLLC_OUT1] = "PLLC_OUT1", + [TEGRA_MUX_PLLM_OUT1] = "PLLM_OUT1", + [TEGRA_MUX_PLLP_OUT2] = "PLLP_OUT2", + [TEGRA_MUX_PLLP_OUT3] = "PLLP_OUT3", + [TEGRA_MUX_PLLP_OUT4] = "PLLP_OUT4", + [TEGRA_MUX_PWM] = "PWM", + [TEGRA_MUX_PWR_INTR] = "PWR_INTR", + [TEGRA_MUX_PWR_ON] = "PWR_ON", + [TEGRA_MUX_RTCK] = "RTCK", + [TEGRA_MUX_SDIO1] = "SDIO1", + [TEGRA_MUX_SDIO2] = "SDIO2", + [TEGRA_MUX_SDIO3] = "SDIO3", + [TEGRA_MUX_SDIO4] = "SDIO4", + [TEGRA_MUX_SFLASH] = "SFLASH", + [TEGRA_MUX_SPDIF] = "SPDIF", + [TEGRA_MUX_SPI1] = "SPI1", + [TEGRA_MUX_SPI2] = "SPI2", + [TEGRA_MUX_SPI2_ALT] = "SPI2_ALT", + [TEGRA_MUX_SPI3] = "SPI3", + [TEGRA_MUX_SPI4] = "SPI4", + [TEGRA_MUX_TRACE] = "TRACE", + [TEGRA_MUX_TWC] = "TWC", + [TEGRA_MUX_UARTA] = "UARTA", + [TEGRA_MUX_UARTB] = "UARTB", + [TEGRA_MUX_UARTC] = "UARTC", + [TEGRA_MUX_UARTD] = "UARTD", + [TEGRA_MUX_UARTE] = "UARTE", + [TEGRA_MUX_ULPI] = "ULPI", + [TEGRA_MUX_VI] = "VI", + [TEGRA_MUX_VI_SENSOR_CLK] = "VI_SENSOR_CLK", + [TEGRA_MUX_XIO] = "XIO", +}; + +static DEFINE_SPINLOCK(mux_lock); + +static const char *pingroup_name(tegra_pingroup_t pg) +{ + if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) + return "<UNKNOWN>"; + + return pingroups[pg].name; +} + +static const char *func_name(tegra_mux_func_t func) +{ + if (func == TEGRA_MUX_RSVD1) + return "RSVD1"; + + if (func == TEGRA_MUX_RSVD2) + return "RSVD2"; + + if (func == TEGRA_MUX_RSVD3) + return "RSVD3"; + + if (func == TEGRA_MUX_RSVD4) + return "RSVD4"; + + if (func == TEGRA_MUX_NONE) + return "NONE"; + + if (func < 0 || func >= TEGRA_MAX_MUX) + return "<UNKNOWN>"; + + return tegra_mux_names[func]; +} + + +static const char *tri_name(unsigned long val) +{ + return val ? "TRISTATE" : "NORMAL"; +} + +static const char *pupd_name(unsigned long val) +{ + switch (val) { + case 0: + return "NORMAL"; + + case 1: + return "PULL_DOWN"; + + case 2: + return "PULL_UP"; + + default: + return "RSVD"; + } +} + + +static inline unsigned long pg_readl(unsigned long offset) +{ + return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset)); +} + +static inline void pg_writel(unsigned long value, unsigned long offset) +{ + writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset)); +} + +int tegra_pinmux_set_func(tegra_pingroup_t pg, tegra_mux_func_t func) +{ + int mux = -1; + int i; + unsigned long reg; + unsigned long flags; + + if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) + return -ERANGE; + + if (pingroups[pg].mux_reg == REG_N) + return -EINVAL; + + if (func < 0) + return -ERANGE; + + if (func & TEGRA_MUX_RSVD) { + mux = func & 0x3; + } else { + for (i = 0; i < 4; i++) { + if (pingroups[pg].funcs[i] == func) { + mux = i; + break; + } + } + } + + if (mux < 0) + return -EINVAL; + + spin_lock_irqsave(&mux_lock, flags); + + reg = pg_readl(TEGRA_PP_MUX_CTL(pingroups[pg].mux_reg)); + reg &= ~(0x3 << pingroups[pg].mux_bit); + reg |= mux << pingroups[pg].mux_bit; + pg_writel(reg, TEGRA_PP_MUX_CTL(pingroups[pg].mux_reg)); + + spin_unlock_irqrestore(&mux_lock, flags); + + return 0; +} + +int tegra_pinmux_set_tristate(tegra_pingroup_t pg, tegra_tristate_t tristate) +{ + unsigned long reg; + unsigned long flags; + + if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) + return -ERANGE; + + if (pingroups[pg].tri_reg == REG_N) + return -EINVAL; + + spin_lock_irqsave(&mux_lock, flags); + + reg = pg_readl(TEGRA_TRI_STATE(pingroups[pg].tri_reg)); + reg &= ~(0x1 << pingroups[pg].tri_bit); + if (tristate) + reg |= 1 << pingroups[pg].tri_bit; + pg_writel(reg, TEGRA_TRI_STATE(pingroups[pg].tri_reg)); + + spin_unlock_irqrestore(&mux_lock, flags); + + return 0; +} + +int tegra_pinmux_set_pullupdown(tegra_pingroup_t pg, tegra_pullupdown_t pupd) +{ + unsigned long reg; + unsigned long flags; + + if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) + return -ERANGE; + + if (pingroups[pg].pupd_reg == REG_N) + return -EINVAL; + + if (pupd != TEGRA_PUPD_NORMAL && + pupd != TEGRA_PUPD_PULL_DOWN && + pupd != TEGRA_PUPD_PULL_UP) + return -EINVAL; + + + spin_lock_irqsave(&mux_lock, flags); + + reg = pg_readl(TEGRA_PP_PU_PD(pingroups[pg].pupd_reg)); + reg &= ~(0x3 << pingroups[pg].pupd_bit); + reg |= pupd << pingroups[pg].pupd_bit; + pg_writel(reg, TEGRA_PP_PU_PD(pingroups[pg].pupd_reg)); + + spin_unlock_irqrestore(&mux_lock, flags); + + return 0; +} + +void tegra_pinmux_config_pingroup(tegra_pingroup_t pingroup, + tegra_mux_func_t func, + tegra_pullupdown_t pupd, + tegra_tristate_t tristate) +{ + int err; + + if (pingroups[pingroup].mux_reg != REG_N) { + err = tegra_pinmux_set_func(pingroup, func); + if (err < 0) + pr_err("pinmux: can't set pingroup %s func to %s: %d\n", + pingroup_name(pingroup), func_name(func), err); + } + + if (pingroups[pingroup].pupd_reg != REG_N) { + err = tegra_pinmux_set_pullupdown(pingroup, pupd); + if (err < 0) + pr_err("pinmux: can't set pingroup %s pullupdown to %s: %d\n", + pingroup_name(pingroup), pupd_name(pupd), err); + } + + if (pingroups[pingroup].tri_reg != REG_N) { + err = tegra_pinmux_set_tristate(pingroup, tristate); + if (err < 0) + pr_err("pinmux: can't set pingroup %s tristate to %s: %d\n", + pingroup_name(pingroup), tri_name(func), err); + } +} + + + +void tegra_pinmux_config_table(struct tegra_pingroup_config *config, int len) +{ + int i; + + for (i = 0; i < len; i++) + tegra_pinmux_config_pingroup(config[i].pingroup, + config[i].func, + config[i].pupd, + config[i].tristate); +} + + + + + +#ifdef CONFIG_DEBUG_FS + +#include <linux/debugfs.h> +#include <linux/seq_file.h> + +static void dbg_pad_field(struct seq_file *s, int len) +{ + seq_putc(s, ','); + + while (len-- > -1) + seq_putc(s, ' '); +} + +static int dbg_pinmux_show(struct seq_file *s, void *unused) +{ + int i; + int len; + + for (i = 0; i < TEGRA_MAX_PINGROUP; i++) { + unsigned long tri; + unsigned long mux; + unsigned long pupd; + + seq_printf(s, "\t{TEGRA_PINGROUP_%s", pingroups[i].name); + len = strlen(pingroups[i].name); + dbg_pad_field(s, 5 - len); + + if (pingroups[i].mux_reg == REG_N) { + seq_printf(s, "TEGRA_MUX_NONE"); + len = strlen("NONE"); + } else { + mux = (pg_readl(TEGRA_PP_MUX_CTL(pingroups[i].mux_reg)) >> + pingroups[i].mux_bit) & 0x3; + if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) { + seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1); + len = 5; + } else { + seq_printf(s, "TEGRA_MUX_%s", + tegra_mux_names[pingroups[i].funcs[mux]]); + len = strlen(tegra_mux_names[pingroups[i].funcs[mux]]); + } + } + dbg_pad_field(s, 13-len); + + if (pingroups[i].mux_reg == REG_N) { + seq_printf(s, "TEGRA_PUPD_NORMAL"); + len = strlen("NORMAL"); + } else { + pupd = (pg_readl(TEGRA_PP_PU_PD(pingroups[i].pupd_reg)) >> + pingroups[i].pupd_bit) & 0x3; + seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd)); + len = strlen(pupd_name(pupd)); + } + dbg_pad_field(s, 9 - len); + + if (pingroups[i].tri_reg == REG_N) { + seq_printf(s, "TEGRA_TRI_NORMAL"); + } else { + tri = (pg_readl(TEGRA_TRI_STATE(pingroups[i].tri_reg)) >> + pingroups[i].tri_bit) & 0x1; + + seq_printf(s, "TEGRA_TRI_%s", tri_name(tri)); + } + seq_printf(s, "},\n"); + } + return 0; +} + +static int dbg_pinmux_open(struct inode *inode, struct file *file) +{ + return single_open(file, dbg_pinmux_show, &inode->i_private); +} + +static const struct file_operations debug_fops = { + .open = dbg_pinmux_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init tegra_pinmux_debuginit(void) +{ + (void) debugfs_create_file("tegra_pinmux", S_IRUGO, + NULL, NULL, &debug_fops); + return 0; +} +late_initcall(tegra_pinmux_debuginit); +#endif -- 1.6.5.6 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [RFC/PATCH 08/10] [ARM] tegra: Add framebuffer driver 2010-03-16 6:41 ` [RFC/PATCH 07/10] [ARM] tegra: add pinmux support konkers at google.com @ 2010-03-16 6:41 ` konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 09/10] [ARM] tegra: harmony: Add harmony board file konkers at google.com ` (2 more replies) 0 siblings, 3 replies; 37+ messages in thread From: konkers at google.com @ 2010-03-16 6:41 UTC (permalink / raw) To: linux-arm-kernel From: Colin Cross <ccross@android.com> Signed-off-by: Colin Cross <ccross@android.com> Signed-off-by: Erik Gilling <konkers@android.com> --- arch/arm/mach-tegra/include/mach/tegra_fb.h | 24 + drivers/video/Kconfig | 11 + drivers/video/Makefile | 1 + drivers/video/tegrafb.c | 620 +++++++++++++++++++++++++++ 4 files changed, 656 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-tegra/include/mach/tegra_fb.h create mode 100644 drivers/video/tegrafb.c diff --git a/arch/arm/mach-tegra/include/mach/tegra_fb.h b/arch/arm/mach-tegra/include/mach/tegra_fb.h new file mode 100644 index 0000000..f173544 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/tegra_fb.h @@ -0,0 +1,24 @@ +/* + * arch/arm/mach-tegra/include/mach/tegra_fb.h + * + * Copyright (C) 2010 Google, Inc. + * Author: Colin Cross <ccross@android.com> + * + * 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. + * + */ + +struct tegra_fb_lcd_data { + int fb_xres; + int fb_yres; + int lcd_xres; + int lcd_yres; + int bits_per_pixel; +}; diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 5a5c303..b2e68e2 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1074,6 +1074,17 @@ config FB_RIVA_BACKLIGHT help Say Y here if you want to control the backlight of your display. +config FB_TEGRA + tristate "NVIDIA Tegra SoC display support" + depends on ARCH_TEGRA && FB = y + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + default FB + help + This driver supports the NVIDIA Tegra systems-on-a-chip. This + driver can not be compiled as a module. + config FB_I810 tristate "Intel 810/815 support (EXPERIMENTAL)" depends on EXPERIMENTAL && FB && PCI && X86_32 && AGP_INTEL diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 4ecb30c..d4a14f2 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -129,6 +129,7 @@ obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o obj-$(CONFIG_FB_CARMINE) += carminefb.o obj-$(CONFIG_FB_MB862XX) += mb862xx/ obj-$(CONFIG_FB_MSM) += msm/ +obj-$(CONFIG_FB_TEGRA) += tegrafb.o # Platform or fallback drivers go here obj-$(CONFIG_FB_UVESA) += uvesafb.o diff --git a/drivers/video/tegrafb.c b/drivers/video/tegrafb.c new file mode 100644 index 0000000..634022b --- /dev/null +++ b/drivers/video/tegrafb.c @@ -0,0 +1,620 @@ +/* + * drivers/video/tegrafb.c + * + * Copyright (C) 2010 Google, Inc. + * Author: Colin Cross <ccross@android.com> + * Travis Geiselbrecht <travis@palm.com> + * + * 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. + * + */ + +#include <linux/fb.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/clk.h> +#include <linux/wait.h> +#include <asm/cacheflush.h> +#include <mach/tegra_fb.h> + +#define DEBUG 1 + +#define DC_CMD_GENERAL_INCR_SYNCPT 0x000 +#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x001 +#define DC_CMD_GENERAL_INCR_SYNCPT_ERROR 0x002 +#define DC_CMD_WIN_A_INCR_SYNCPT 0x008 +#define DC_CMD_WIN_A_INCR_SYNCPT_CNTRL 0x009 +#define DC_CMD_WIN_A_INCR_SYNCPT_ERROR 0x00a +#define DC_CMD_WIN_B_INCR_SYNCPT 0x010 +#define DC_CMD_WIN_B_INCR_SYNCPT_CNTRL 0x011 +#define DC_CMD_WIN_B_INCR_SYNCPT_ERROR 0x012 +#define DC_CMD_WIN_C_INCR_SYNCPT 0x018 +#define DC_CMD_WIN_C_INCR_SYNCPT_CNTRL 0x019 +#define DC_CMD_WIN_C_INCR_SYNCPT_ERROR 0x01a +#define DC_CMD_CONT_SYNCPT_VSYNC 0x028 +#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031 +#define DC_CMD_DISPLAY_COMMAND 0x032 +#define DC_CMD_SIGNAL_RAISE 0x033 +#define DC_CMD_INT_STATUS 0x037 +#define DC_CMD_INT_MASK 0x038 +#define DC_CMD_INT_ENABLE 0x039 +#define DC_CMD_INT_TYPE 0x03a +#define DC_CMD_INT_POLARITY 0x03b +#define DC_CMD_SIGNAL_RAISE1 0x03c +#define DC_CMD_SIGNAL_RAISE2 0x03d +#define DC_CMD_SIGNAL_RAISE3 0x03e +#define DC_CMD_STATE_ACCESS 0x040 +#define DC_CMD_STATE_CONTROL 0x041 +#define DC_CMD_DISPLAY_WINDOW_HEADER 0x042 +#define DC_CMD_REG_ACT_CONTROL 0x043 +#define DC_WINC_A_COLOR_PALETTE 0x500 +#define DC_WINC_A_PALETTE_COLOR_EXT 0x600 +#define DC_WIN_A_WIN_OPTIONS 0x700 +#define DC_WIN_A_BYTE_SWAP 0x701 +#define DC_WIN_A_BUFFER_CONTROL 0x702 +#define DC_WIN_A_COLOR_DEPTH 0x703 +#define DC_WIN_A_POSITION 0x704 +#define DC_WIN_A_SIZE 0x705 +#define DC_WIN_A_PRESCALED_SIZE 0x706 +#define DC_WIN_A_H_INITIAL_DDA 0x707 +#define DC_WIN_A_V_INITIAL_DDA 0x708 +#define DC_WIN_A_DDA_INCREMENT 0x709 +#define DC_WIN_A_LINE_STRIDE 0x70a +#define DC_WIN_A_BUF_STRIDE 0x70b +#define DC_WINBUF_A_START_ADDR 0x800 +#define DC_WINBUF_A_ADDR_H_OFFSET 0x806 +#define DC_WINBUF_A_ADDR_V_OFFSET 0x808 + + +#define DC_INT_CTXSW (1<<0) +#define DC_INT_FRAME_END (1<<1) +#define DC_INT_V_BLANK (1<<2) +#define DC_INT_H_BLANK (1<<3) +#define DC_INT_V_PULSE3 (1<<4) + +#define DC_COLOR_DEPTH_P1 0 +#define DC_COLOR_DEPTH_P2 1 +#define DC_COLOR_DEPTH_P4 2 +#define DC_COLOR_DEPTH_P8 3 +#define DC_COLOR_DEPTH_B4G4R4A4 4 +#define DC_COLOR_DEPTH_B5G5R5A 5 +#define DC_COLOR_DEPTH_B5G6R5 6 +#define DC_COLOR_DEPTH_AB5G5R5 7 +#define DC_COLOR_DEPTH_B8G8R8A8 12 +#define DC_COLOR_DEPTH_R8G8B8A8 13 +#define DC_COLOR_DEPTH_B6x2G6x2R6x2A8 14 +#define DC_COLOR_DEPTH_R6x2G6x2B6x2A8 15 +#define DC_COLOR_DEPTH_YCbCr422 16 +#define DC_COLOR_DEPTH_YUV422 17 +#define DC_COLOR_DEPTH_YCbCr420P 18 +#define DC_COLOR_DEPTH_YUV420P 19 +#define DC_COLOR_DEPTH_YCbCr422P 20 +#define DC_COLOR_DEPTH_YUV422P 21 +#define DC_COLOR_DEPTH_YCbCr422R 22 +#define DC_COLOR_DEPTH_YUV422R 23 +#define DC_COLOR_DEPTH_YCbCr422RA 24 +#define DC_COLOR_DEPTH_YUV422RA 25 + +struct tegra_fb_info { + struct clk *clk; + struct resource *reg_mem; + struct resource *fb_mem; + void __iomem *reg_base; + wait_queue_head_t event_wq; + unsigned int wait_condition; + int lcd_xres; + int lcd_yres; + int irq; +}; + +static void tegra_fb_writel(struct tegra_fb_info *tegra_fb, u32 val, unsigned long reg) +{ + writel(val, tegra_fb->reg_base + reg*sizeof(u32)); +} + +static u32 tegra_fb_readl(struct tegra_fb_info *tegra_fb, unsigned long reg) +{ + return readl(tegra_fb->reg_base + reg*sizeof(u32)); +} + +/* palette attary used by the fbcon */ +u32 pseudo_palette[16]; + +irqreturn_t tegra_fb_irq(int irq, void *ptr) +{ + struct fb_info *info = ptr; + struct tegra_fb_info *tegra_fb = info->par; + + u32 reg = tegra_fb_readl(tegra_fb, DC_CMD_INT_STATUS); + tegra_fb_writel(tegra_fb, reg, DC_CMD_INT_STATUS); + + tegra_fb->wait_condition = 1; + wake_up(&tegra_fb->event_wq); + return IRQ_HANDLED; +} + +static int tegra_fb_wait_for_event(struct tegra_fb_info *tegra_fb, unsigned long timeout, u32 irq_mask) +{ + u32 reg; + + tegra_fb->wait_condition = 0; + + reg = tegra_fb_readl(tegra_fb, DC_CMD_INT_MASK); + reg |= irq_mask; + tegra_fb_writel(tegra_fb, reg, DC_CMD_INT_MASK); + + /* Clear any pending interrupt */ + tegra_fb_writel(tegra_fb, irq_mask, DC_CMD_INT_STATUS); + + tegra_fb_writel(tegra_fb, irq_mask, DC_CMD_INT_ENABLE); + + /* Wait for the irq to fire */ + wait_event_interruptible_timeout(tegra_fb->event_wq, tegra_fb->wait_condition, timeout); + + tegra_fb_writel(tegra_fb, 0, DC_CMD_INT_ENABLE); + + if (!tegra_fb->wait_condition) { + pr_warning("%s: wait for vsync timed out\n", __func__); + return 1; + } + return 0; +} + +/* Writes to many registers in the display block are buffered. + * tegra_fb_activate requests an update of the main registers from their + * double-buffered registers, which takes effect at the end of the next frame, + * and then waits for the frame_end IRQ. + */ +static void tegra_fb_activate(struct tegra_fb_info *tegra_fb) +{ + int vsync_count = 0; + + if (unlikely(tegra_fb_readl(tegra_fb, DC_CMD_STATE_CONTROL) & 3)) { + pr_warning("%s: update already activated!\n", __func__); + return; + } + + tegra_fb_writel(tegra_fb, (1 << 8) | (1 << 9), DC_CMD_STATE_CONTROL); + tegra_fb_writel(tegra_fb, (1 << 0) | (1 << 1), DC_CMD_STATE_CONTROL); + while (tegra_fb_readl(tegra_fb, DC_CMD_STATE_CONTROL) & 3) { + vsync_count++; + if (tegra_fb_wait_for_event(tegra_fb, HZ/10, DC_INT_FRAME_END)) + break; + } + if (unlikely(vsync_count > 1)) + pr_warning("%s: waited for %d vsyncs\n", __func__, vsync_count); +} + + +static int tegra_fb_open(struct fb_info *info, int user) +{ + return 0; +} + +static int tegra_fb_release(struct fb_info *info, int user) +{ + return 0; +} + +static int tegra_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) +{ + if ((var->xres != info->var.xres) || + (var->yres != info->var.yres) || + (var->xres_virtual != info->var.xres_virtual) || + (var->yres_virtual != info->var.yres_virtual) || + (var->grayscale != info->var.grayscale)) + return -EINVAL; + return 0; +} + +static int tegra_fb_set_par(struct fb_info *info) +{ + struct tegra_fb_info *tegra_fb = info->par; + struct fb_var_screeninfo *var = &info->var; + struct fb_fix_screeninfo *fix = &info->fix; + u32 color_depth; + unsigned int h_dda; + unsigned int v_dda; + + /* we only support RGB ordering for now */ + switch (var->bits_per_pixel) { + case 32: + case 24: + var->red.offset = 0; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 16; + var->blue.length = 8; + color_depth = DC_COLOR_DEPTH_B8G8R8A8; + break; + case 16: + var->red.offset = 11; + var->red.length = 5; + var->green.offset = 5; + var->green.length = 6; + var->blue.offset = 0; + var->blue.length = 5; + color_depth = DC_COLOR_DEPTH_B5G6R5; + break; + default: + return -1; + } + fix->line_length = var->xres * var->bits_per_pixel / 8; + + h_dda = (var->xres * 0x1000) / (tegra_fb->lcd_xres - 1); + v_dda = (var->yres * 0x1000) / (tegra_fb->lcd_yres - 1); + + tegra_fb_writel(tegra_fb, tegra_fb->lcd_yres<<16 | tegra_fb->lcd_xres, + DC_WIN_A_SIZE); + tegra_fb_writel(tegra_fb, var->yres<<16 | fix->line_length, + DC_WIN_A_PRESCALED_SIZE); + tegra_fb_writel(tegra_fb, 0, DC_WIN_A_H_INITIAL_DDA); + tegra_fb_writel(tegra_fb, 0, DC_WIN_A_V_INITIAL_DDA); + tegra_fb_writel(tegra_fb, v_dda << 16 | h_dda, DC_WIN_A_DDA_INCREMENT); + tegra_fb_writel(tegra_fb, color_depth, DC_WIN_A_COLOR_DEPTH); + tegra_fb_writel(tegra_fb, fix->line_length, DC_WIN_A_LINE_STRIDE); + return 0; +} + +static int tegra_fb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, struct fb_info *info) +{ + struct fb_var_screeninfo *var = &info->var; + + if (info->fix.visual == FB_VISUAL_TRUECOLOR || + info->fix.visual == FB_VISUAL_DIRECTCOLOR) { + u32 v; + + if (regno >= 16) + return -EINVAL; + + v = (red << var->red.offset) | + (green << var->green.offset) | + (blue << var->blue.offset); + + ((u32 *)info->pseudo_palette)[regno] = v; + } + + return 0; +} + +static int tegra_fb_blank(int blank, struct fb_info *info) +{ + return 0; +} + +static int tegra_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) +{ + struct tegra_fb_info *tegra_fb = info->par; + char __iomem *flush_start; + char __iomem *flush_end; + u32 addr; + + flush_start = info->screen_base + (var->yoffset * info->fix.line_length); + flush_end = flush_start + (var->yres * info->fix.line_length); + + info->var.xoffset = var->xoffset; + info->var.yoffset = var->yoffset; + + addr = info->fix.smem_start + (var->yoffset * info->fix.line_length) + + (var->xoffset * (var->bits_per_pixel/8)); + + tegra_fb_writel(tegra_fb, addr, DC_WINBUF_A_START_ADDR); + tegra_fb_activate(tegra_fb); + return 0; +} + +static void tegra_fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) +{ + cfb_fillrect(info, rect); +} + +static void tegra_fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) +{ + cfb_copyarea(info, region); +} + +static void tegra_fb_imageblit(struct fb_info *info, const struct fb_image *image) +{ + cfb_imageblit(info, image); +} + +static int tegra_fb_cursor(struct fb_info *info, struct fb_cursor *cursor) +{ + return 0; +} + +static int tegra_fb_sync(struct fb_info *info) +{ + return 0; +} + +#ifdef DEBUG +#define DUMP_REG(a) pr_info("%-32s\t%03x\t%08x\n", #a, a, tegra_fb_readl(tegra_fb, a)); +static void dump_regs(struct tegra_fb_info *tegra_fb) +{ + DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT); + DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT_CNTRL); + DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT_ERROR); + DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT); + DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT_CNTRL); + DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT_ERROR); + DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT); + DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT_CNTRL); + DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT_ERROR); + DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT); + DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT_CNTRL); + DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT_ERROR); + DUMP_REG(DC_CMD_CONT_SYNCPT_VSYNC); + DUMP_REG(DC_CMD_DISPLAY_COMMAND_OPTION0); + DUMP_REG(DC_CMD_DISPLAY_COMMAND); + DUMP_REG(DC_CMD_SIGNAL_RAISE); + DUMP_REG(DC_CMD_INT_STATUS); + DUMP_REG(DC_CMD_INT_MASK); + DUMP_REG(DC_CMD_INT_ENABLE); + DUMP_REG(DC_CMD_INT_TYPE); + DUMP_REG(DC_CMD_INT_POLARITY); + DUMP_REG(DC_CMD_SIGNAL_RAISE1); + DUMP_REG(DC_CMD_SIGNAL_RAISE2); + DUMP_REG(DC_CMD_SIGNAL_RAISE3); + DUMP_REG(DC_CMD_STATE_ACCESS); + DUMP_REG(DC_CMD_STATE_CONTROL); + DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER); + DUMP_REG(DC_CMD_REG_ACT_CONTROL); + tegra_fb_writel(tegra_fb, 1<<4, DC_CMD_DISPLAY_WINDOW_HEADER); + DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER); + DUMP_REG(DC_WINC_A_COLOR_PALETTE); + DUMP_REG(DC_WINC_A_PALETTE_COLOR_EXT); + DUMP_REG(DC_WIN_A_WIN_OPTIONS); + DUMP_REG(DC_WIN_A_BYTE_SWAP); + DUMP_REG(DC_WIN_A_BUFFER_CONTROL); + DUMP_REG(DC_WIN_A_COLOR_DEPTH); + DUMP_REG(DC_WIN_A_POSITION); + DUMP_REG(DC_WIN_A_SIZE); + DUMP_REG(DC_WIN_A_PRESCALED_SIZE); + DUMP_REG(DC_WIN_A_H_INITIAL_DDA); + DUMP_REG(DC_WIN_A_V_INITIAL_DDA); + DUMP_REG(DC_WIN_A_DDA_INCREMENT); + DUMP_REG(DC_WIN_A_LINE_STRIDE); + DUMP_REG(DC_WIN_A_BUF_STRIDE); + DUMP_REG(DC_WINBUF_A_START_ADDR); + DUMP_REG(DC_WINBUF_A_ADDR_H_OFFSET); + DUMP_REG(DC_WINBUF_A_ADDR_V_OFFSET); +} +#endif + +static struct fb_ops tegra_fb_ops = { + .owner = THIS_MODULE, + .fb_open = tegra_fb_open, + .fb_release = tegra_fb_release, + .fb_check_var = tegra_fb_check_var, + .fb_set_par = tegra_fb_set_par, + .fb_setcolreg = tegra_fb_setcolreg, + .fb_pan_display = tegra_fb_pan_display, + .fb_blank = tegra_fb_blank, + .fb_fillrect = tegra_fb_fillrect, + .fb_copyarea = tegra_fb_copyarea, + .fb_imageblit = tegra_fb_imageblit, + .fb_cursor = tegra_fb_cursor, + .fb_sync = tegra_fb_sync, +}; + +static int tegra_plat_probe(struct platform_device *pdev) +{ + struct fb_info *info; + struct tegra_fb_info *tegra_fb; + struct clk *clk; + struct resource *res; + struct resource *reg_mem; + struct resource *fb_mem; + int ret = 0; + void __iomem *reg_base; + void __iomem *fb_base; + unsigned long fb_size; + unsigned long fb_phys; + int irq; + struct tegra_fb_lcd_data *lcd_data = pdev->dev.platform_data; + + info = framebuffer_alloc(sizeof(struct tegra_fb_info), &pdev->dev); + if (!info) { + ret = -ENOMEM; + goto err; + } + + irq = platform_get_irq(pdev, 0); + if (irq <= 0) { + pr_debug("%s: no irq\n", pdev->name); + ret = -ENOENT; + goto err_free; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + pr_debug("%s: no mem resource\n", pdev->name); + ret = -ENOENT; + goto err_free; + } + + reg_mem = request_mem_region(res->start, resource_size(res), pdev->name); + if (!reg_mem) { + pr_debug("%s: request_mem_region failed\n", pdev->name); + ret = -EBUSY; + goto err_free; + } + + reg_base = ioremap(res->start, resource_size(res)); + if (!reg_base) { + pr_debug("%s: registers can't be mapped\n", pdev->name); + ret = -EBUSY; + goto err_release_resource_reg; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + pr_debug("%s: no mem resource\n", pdev->name); + ret = -ENOENT; + goto err_iounmap_reg; + } + + fb_mem = request_mem_region(res->start, resource_size(res), pdev->name); + if (!fb_mem) { + pr_debug("%s: request_mem_region failed\n", pdev->name); + ret = -EBUSY; + goto err_iounmap_reg; + } + + fb_size = resource_size(res); + fb_phys = res->start; + fb_base = ioremap_nocache(fb_phys, fb_size); + if (!fb_base) { + pr_debug("%s: fb can't be mapped\n", pdev->name); + ret = -EBUSY; + goto err_release_resource_fb; + } + + clk = clk_get(&pdev->dev, NULL); + if (!clk) { + pr_debug("%s: can't get clock\n", pdev->name); + ret = -ENOENT; + goto err_iounmap_fb; + } + clk_enable(clk); + + tegra_fb = info->par; + tegra_fb->clk = clk; + tegra_fb->fb_mem = fb_mem; + tegra_fb->reg_mem = reg_mem; + tegra_fb->reg_base = reg_base; + tegra_fb->irq = irq; + tegra_fb->lcd_xres = lcd_data->lcd_xres; + tegra_fb->lcd_yres = lcd_data->lcd_yres; + + info->fbops = &tegra_fb_ops; + info->pseudo_palette = pseudo_palette; + info->screen_base = fb_base; + info->screen_size = fb_size; + + strlcpy(info->fix.id, "tegra_fb", sizeof(info->fix.id)); + info->fix.type = FB_TYPE_PACKED_PIXELS; + info->fix.visual = FB_VISUAL_TRUECOLOR; + info->fix.xpanstep = 1; + info->fix.ypanstep = 1; + info->fix.accel = FB_ACCEL_NONE; + info->fix.smem_start = fb_phys; + info->fix.smem_len = fb_size; + + info->var.xres = lcd_data->fb_xres; + info->var.yres = lcd_data->fb_yres; + info->var.xres_virtual = lcd_data->fb_xres; + info->var.yres_virtual = lcd_data->fb_yres*2; + info->var.bits_per_pixel = lcd_data->bits_per_pixel; + info->var.activate = FB_ACTIVATE_NOW; + info->var.height = -1; + info->var.width = -1; + info->var.pixclock = 24500; + info->var.left_margin = 0; + info->var.right_margin = 0; + info->var.upper_margin = 0; + info->var.lower_margin = 0; + info->var.hsync_len = 0; + info->var.vsync_len = 0; + info->var.vmode = FB_VMODE_NONINTERLACED; + + if (request_irq(irq, tegra_fb_irq, IRQF_DISABLED, + dev_name(&pdev->dev), info)) { + pr_debug("%s: request_irq %d failed\n", + pdev->name, irq); + ret = -EBUSY; + goto err_clk_disable; + } + + init_waitqueue_head(&tegra_fb->event_wq); + + /* Enable writes to Window A */ + tegra_fb_writel(tegra_fb, 1<<4, DC_CMD_DISPLAY_WINDOW_HEADER); + + tegra_fb_set_par(info); + + dev_info(&pdev->dev, "base address: %08x (%08x)\n", + (unsigned int)info->fix.smem_start, + (unsigned int)info->screen_base); + +#ifdef DEBUG + dump_regs(tegra_fb); +#endif + + register_framebuffer(info); + platform_set_drvdata(pdev, info); + return 0; + +err_clk_disable: + clk_disable(clk); +err_iounmap_fb: + iounmap(fb_base); +err_release_resource_fb: + release_resource(fb_mem); +err_iounmap_reg: + iounmap(reg_base); +err_release_resource_reg: + release_resource(reg_mem); +err_free: + framebuffer_release(info); +err: + return ret; +} + +static int tegra_plat_remove(struct platform_device *pdev) +{ + struct fb_info *fb = platform_get_drvdata(pdev); + struct tegra_fb_info *tegra_fb = fb->par; + clk_disable(tegra_fb->clk); + iounmap(fb->screen_base); + release_resource(tegra_fb->fb_mem); + iounmap(tegra_fb->reg_base); + release_resource(tegra_fb->reg_mem); + framebuffer_release(fb); + return 0; +} + +struct platform_driver tegra_platform_driver = { + .probe = tegra_plat_probe, + .remove = tegra_plat_remove, + .driver = { + .name = "tegrafb", + .owner = THIS_MODULE, + }, +}; + +static int __init tegra_fb_init(void) +{ + int e; + e = platform_driver_register(&tegra_platform_driver); + if (e) { + pr_info("tegrafb: platform_driver_register failed\n"); + return e; + } + return e; +} + +static void __exit tegra_exit(void) +{ + platform_driver_unregister(&tegra_platform_driver); +} + +module_exit(tegra_exit); +module_init(tegra_fb_init); -- 1.6.5.6 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [RFC/PATCH 09/10] [ARM] tegra: harmony: Add harmony board file 2010-03-16 6:41 ` [RFC/PATCH 08/10] [ARM] tegra: Add framebuffer driver konkers at google.com @ 2010-03-16 6:41 ` konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 10/10] [ARM] tegra: Add harmony_defconfig konkers at google.com 2010-03-17 8:21 ` [RFC/PATCH 09/10] [ARM] tegra: harmony: Add harmony board file Mike Rapoport 2010-03-16 7:57 ` [RFC/PATCH 08/10] [ARM] tegra: Add framebuffer driver Jaya Kumar 2010-03-18 8:47 ` Russell King - ARM Linux 2 siblings, 2 replies; 37+ messages in thread From: konkers at google.com @ 2010-03-16 6:41 UTC (permalink / raw) To: linux-arm-kernel From: Colin Cross <ccross@android.com> Signed-off-by: Colin Cross <ccross@android.com> Signed-off-by: Erik Gilling <konkers@android.com> --- arch/arm/mach-tegra/Makefile | 4 + arch/arm/mach-tegra/board-harmony-panel.c | 75 ++++++++++++++ arch/arm/mach-tegra/board-harmony-pinmux.c | 144 ++++++++++++++++++++++++++++ arch/arm/mach-tegra/board-harmony.c | 129 +++++++++++++++++++++++++ arch/arm/mach-tegra/board-harmony.h | 22 ++++ 5 files changed, 374 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-tegra/board-harmony-panel.c create mode 100644 arch/arm/mach-tegra/board-harmony-pinmux.c create mode 100644 arch/arm/mach-tegra/board-harmony.c create mode 100644 arch/arm/mach-tegra/board-harmony.h diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 5e47a71..c832aa8 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -9,3 +9,7 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o + +obj-${CONFIG_MACH_HARMONY} += board-harmony.o +obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o +obj-${CONFIG_MACH_HARMONY} += board-harmony-panel.o diff --git a/arch/arm/mach-tegra/board-harmony-panel.c b/arch/arm/mach-tegra/board-harmony-panel.c new file mode 100644 index 0000000..9fbdacb --- /dev/null +++ b/arch/arm/mach-tegra/board-harmony-panel.c @@ -0,0 +1,75 @@ +/* + * arch/arm/mach-tegra/board-harmony-panel.c + * + * Copyright (C) 2010 Google, Inc. + * + * 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. + * + */ + +#include <linux/resource.h> +#include <linux/platform_device.h> +#include <asm/mach-types.h> +#include <mach/irqs.h> +#include <mach/iomap.h> +#include <mach/tegra_fb.h> + +/* Framebuffer */ +static struct resource fb_resource[] = { + [0] = { + .start = INT_DISPLAY_GENERAL, + .end = INT_DISPLAY_GENERAL, + .flags = IORESOURCE_IRQ, + }, + [1] = { + .start = TEGRA_DISPLAY_BASE, + .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = 0x1c012000, + .end = 0x1c012000 + 0x500000 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct tegra_fb_lcd_data tegra_fb_lcd_platform_data = { + .lcd_xres = 1024, + .lcd_yres = 600, + .fb_xres = 1024, + .fb_yres = 600, + .bits_per_pixel = 16, +}; + +static struct platform_device tegra_fb_device = { + .name = "tegrafb", + .id = 0, + .resource = fb_resource, + .num_resources = ARRAY_SIZE(fb_resource), + .dev = { + .platform_data = &tegra_fb_lcd_platform_data, + }, +}; + +static int __init harmony_init_panel(void) { + int ret; + + if (!machine_is_harmony()) + return 0; + + ret = platform_device_register(&tegra_fb_device); + if (ret != 0) + return ret; + + return 0; +} + +device_initcall(harmony_init_panel); + diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c new file mode 100644 index 0000000..50b15d5 --- /dev/null +++ b/arch/arm/mach-tegra/board-harmony-pinmux.c @@ -0,0 +1,144 @@ +/* + * arch/arm/mach-tegra/board-harmony-pinmux.c + * + * Copyright (C) 2010 Google, Inc. + * + * 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. + * + */ + +#include <linux/kernel.h> +#include <mach/pinmux.h> + +#include "board-harmony.h" + +static struct tegra_pingroup_config harmony_pinmux[] = { + {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_OSC, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_DTA, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_DTB, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_DTC, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_DTD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_GMD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_GPU, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_KBCB, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_KBCD, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LCSN, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_LSDA, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_LSDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SDC, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, +}; + +void harmony_pinmux_init(void) +{ + tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux)); +} diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c new file mode 100644 index 0000000..55565a5 --- /dev/null +++ b/arch/arm/mach-tegra/board-harmony.c @@ -0,0 +1,129 @@ +/* + * arch/arm/mach-tegra/board-harmony.c + * + * Copyright (C) 2010 Google, Inc. + * + * 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. + * + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/serial_8250.h> +#include <linux/clk.h> +#include <linux/dma-mapping.h> +#include <linux/pda_power.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> +#include <asm/setup.h> + +#include <mach/io.h> +#include <mach/iomap.h> +#include <mach/irqs.h> +#include <mach/iomap.h> + +#include "board.h" +#include "board-harmony.h" + +/* NVidia bootloader tags */ +#define ATAG_NVIDIA 0x41000801 + +#define ATAG_NVIDIA_RM 0x1 +#define ATAG_NVIDIA_DISPLAY 0x2 +#define ATAG_NVIDIA_FRAMEBUFFER 0x3 +#define ATAG_NVIDIA_CHIPSHMOO 0x4 +#define ATAG_NVIDIA_CHIPSHMOOPHYS 0x5 +#define ATAG_NVIDIA_PRESERVED_MEM_0 0x10000 +#define ATAG_NVIDIA_PRESERVED_MEM_N 2 +#define ATAG_NVIDIA_FORCE_32 0x7fffffff + +struct tag_tegra { + __u32 bootarg_key; + __u32 bootarg_len; + char bootarg[1]; +}; + +static int __init parse_tag_nvidia(const struct tag *tag) +{ + + return 0; +} +__tagtable(ATAG_NVIDIA, parse_tag_nvidia); + +static struct plat_serial8250_port debug_uart_platform_data[] = { + { + .membase = IO_ADDRESS(TEGRA_UARTD_BASE), + .mapbase = TEGRA_UARTD_BASE, + .irq = INT_UARTD, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = 216000000/16 * 16, + }, { + .flags = 0 + } +}; + +static struct platform_device debug_uart = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = debug_uart_platform_data, + }, +}; + +static struct platform_device *harmony_devices[] __initdata = { + &debug_uart, +}; + +static void __init tegra_harmony_fixup(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + mi->nr_banks = 2; + mi->bank[0].start = PHYS_OFFSET; + mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET); + mi->bank[0].size = 448 * SZ_1M; + mi->bank[1].start = SZ_512M; + mi->bank[1].node = PHYS_TO_NID(SZ_512M); + mi->bank[1].size = SZ_512M; +} + +static void __init tegra_harmony_init(void) +{ + struct clk *clk; + + tegra_common_init(); + + clk = clk_get_sys(NULL, "pll_p"); + clk_enable(clk); + clk_set_rate(clk, 216000000); + + clk = clk_get_sys("uart.3", NULL); + clk_set_rate(clk, 216000000); + clk_enable(clk); + + harmony_pinmux_init(); + + platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices)); +} + +MACHINE_START(HARMONY, "harmony") + .boot_params = 0x00000100, + .phys_io = IO_APB_PHYS, + .io_pg_offst = ((IO_APB_VIRT) >> 18) & 0xfffc, + .fixup = tegra_harmony_fixup, + .init_irq = tegra_init_irq, + .init_machine = tegra_harmony_init, + .map_io = tegra_map_common_io, + .timer = &tegra_timer, +MACHINE_END diff --git a/arch/arm/mach-tegra/board-harmony.h b/arch/arm/mach-tegra/board-harmony.h new file mode 100644 index 0000000..09ca775 --- /dev/null +++ b/arch/arm/mach-tegra/board-harmony.h @@ -0,0 +1,22 @@ +/* + * arch/arm/mach-tegra/board-harmony.h + * + * Copyright (C) 2010 Google, Inc. + * + * 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. + * + */ + +#ifndef _MACH_TEGRA_BOARD_HARMONY_H +#define _MACH_TEGRA_BOARD_HARMONY_H + +void harmony_pinmux_init(void); + +#endif -- 1.6.5.6 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [RFC/PATCH 10/10] [ARM] tegra: Add harmony_defconfig 2010-03-16 6:41 ` [RFC/PATCH 09/10] [ARM] tegra: harmony: Add harmony board file konkers at google.com @ 2010-03-16 6:41 ` konkers at google.com 2010-03-17 8:21 ` [RFC/PATCH 09/10] [ARM] tegra: harmony: Add harmony board file Mike Rapoport 1 sibling, 0 replies; 37+ messages in thread From: konkers at google.com @ 2010-03-16 6:41 UTC (permalink / raw) To: linux-arm-kernel From: Colin Cross <ccross@android.com> Signed-off-by: Colin Cross <ccross@android.com> Signed-off-by: Erik Gilling <konkers@android.com> --- arch/arm/configs/harmony_defconfig | 1569 ++++++++++++++++++++++++++++++++++++ 1 files changed, 1569 insertions(+), 0 deletions(-) create mode 100644 arch/arm/configs/harmony_defconfig diff --git a/arch/arm/configs/harmony_defconfig b/arch/arm/configs/harmony_defconfig new file mode 100644 index 0000000..d2a0e93 --- /dev/null +++ b/arch/arm/configs/harmony_defconfig @@ -0,0 +1,1569 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.34-rc1 +# Mon Mar 15 21:20:01 2010 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_LOCKBREAK=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_SWAP=y +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_RCU_FAST_NO_HZ is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_CGROUPS=y +CONFIG_CGROUP_DEBUG=y +# CONFIG_CGROUP_NS is not set +CONFIG_CGROUP_FREEZER=y +# CONFIG_CGROUP_DEVICE is not set +# CONFIG_CPUSETS is not set +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +# CONFIG_CGROUP_MEM_RES_CTLR is not set +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_CGROUP is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +CONFIG_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set +CONFIG_ARCH_TEGRA=y +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_U8500 is not set + +# +# NVIDIA Tegra options +# +CONFIG_ARCH_TEGRA_2x_SOC=y +CONFIG_MACH_HARMONY=y +CONFIG_TEGRA_DEBUG_UART_NONE=y +# CONFIG_TEGRA_DEBUG_UARTA is not set +# CONFIG_TEGRA_DEBUG_UARTB is not set +# CONFIG_TEGRA_DEBUG_UARTC is not set +# CONFIG_TEGRA_DEBUG_UARTD is not set +# CONFIG_TEGRA_DEBUG_UARTE is not set + +# +# Processor Type +# +CONFIG_CPU_32v6K=y +CONFIG_CPU_V7=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_HAS_TLS_REG=y +CONFIG_OUTER_CACHE=y +CONFIG_CACHE_L2X0=y +CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_CPU_HAS_PMU=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set +CONFIG_ARM_GIC=y +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_SMP=y +CONFIG_HAVE_ARM_SCU=y +CONFIG_HAVE_ARM_TWD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_NR_CPUS=2 +CONFIG_HOTPLUG_CPU=y +CONFIG_LOCAL_TIMERS=y +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_HZ=100 +# CONFIG_THUMB2_KERNEL is not set +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +CONFIG_HIGHMEM=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mem=448M at 0M console=ttyS0,115200n8 earlyprintk init=/bin/ash" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y +CONFIG_VFPv3=y +# CONFIG_NEON is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_APM_EMULATION is not set +# CONFIG_PM_RUNTIME is not set +CONFIG_PM_OPS=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=y +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +CONFIG_INET_ESP=y +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +# CONFIG_IPV6_ROUTE_INFO is not set +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MIP6=y +CONFIG_INET6_XFRM_TUNNEL=y +CONFIG_INET6_TUNNEL=y +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=y +CONFIG_IPV6_MULTIPLE_TABLES=y +# CONFIG_IPV6_SUBTREES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_L2CAP=y +CONFIG_BT_SCO=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +# CONFIG_BT_BNEP_MC_FILTER is not set +# CONFIG_BT_BNEP_PROTO_FILTER is not set +CONFIG_BT_HIDP=y + +# +# Bluetooth device drivers +# +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +# CONFIG_BT_HCIUART_BCSP is not set +CONFIG_BT_HCIUART_LL=y +# CONFIG_BT_HCIVHCI is not set +# CONFIG_BT_MRVL is not set +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +CONFIG_RFKILL=y +# CONFIG_RFKILL_INPUT is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_DS1682 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IWMC3200TOP is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +CONFIG_BLK_DEV_DM=y +CONFIG_DM_DEBUG=y +CONFIG_DM_CRYPT=y +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_UEVENT=y +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +CONFIG_SMC91X=y +# CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_WLAN=y +# CONFIG_HOSTAP is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_MPPE=y +# CONFIG_PPPOE is not set +# CONFIG_PPPOL2TP is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=y +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_UINPUT=y +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_DEVKMEM is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +# CONFIG_I2C_CHARDEV is not set +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_IT8761E is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# + +# +# AC97 GPIO expanders: +# +CONFIG_W1=y + +# +# 1-wire Bus Masters +# +CONFIG_W1_MASTER_DS2482=y +# CONFIG_W1_MASTER_DS1WM is not set +# CONFIG_W1_MASTER_GPIO is not set + +# +# 1-wire Slaves +# +# CONFIG_W1_SLAVE_THERM is not set +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_DS2431 is not set +# CONFIG_W1_SLAVE_DS2433 is not set +# CONFIG_W1_SLAVE_DS2760 is not set +# CONFIG_W1_SLAVE_BQ27000 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PDA_POWER=y +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set +CONFIG_REGULATOR=y +CONFIG_REGULATOR_DEBUG=y +# CONFIG_REGULATOR_DUMMY is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +# CONFIG_REGULATOR_BQ24022 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_LP3971 is not set +CONFIG_REGULATOR_TPS65023=y +# CONFIG_REGULATOR_TPS6507X is not set +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +# CONFIG_VIDEO_ALLOW_V4L1 is not set +CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +CONFIG_IR_CORE=y +CONFIG_VIDEO_IR=y +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=y +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_MEDIA_TUNER_SIMPLE=y +CONFIG_MEDIA_TUNER_TDA8290=y +CONFIG_MEDIA_TUNER_TDA9887=y +CONFIG_MEDIA_TUNER_TEA5761=y +CONFIG_MEDIA_TUNER_TEA5767=y +CONFIG_MEDIA_TUNER_MT20XX=y +CONFIG_MEDIA_TUNER_XC2028=y +CONFIG_MEDIA_TUNER_XC5000=y +CONFIG_MEDIA_TUNER_MC44S803=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_SOC_CAMERA is not set +CONFIG_RADIO_ADAPTERS=y +# CONFIG_I2C_SI4713 is not set +# CONFIG_RADIO_SI4713 is not set +# CONFIG_RADIO_SI470X is not set +# CONFIG_RADIO_TEA5764 is not set +# CONFIG_RADIO_SAA7706H is not set +# CONFIG_RADIO_TEF6862 is not set +CONFIG_DAB=y + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=y +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_TEGRA=y +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_LOGO is not set +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set +# CONFIG_HID_PID is not set + +# +# Special HID drivers +# +# CONFIG_HID_APPLE is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_WACOM is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DEBUG=y +CONFIG_USB_GADGET_DEBUG_FILES=y +CONFIG_USB_GADGET_DEBUG_FS=y +CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +CONFIG_USB_GADGET_R8A66597=y +CONFIG_USB_R8A66597=y +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_NOKIA is not set +# CONFIG_USB_G_MULTI is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ULPI is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_UNSAFE_RESUME=y + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +# CONFIG_MMC_BLOCK_BOUNCE is not set +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +# CONFIG_RTC_INTF_SYSFS is not set +# CONFIG_RTC_INTF_PROC is not set +# CONFIG_RTC_INTF_DEV is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +CONFIG_STAGING=y +# CONFIG_STAGING_EXCLUDE_BUILD is not set +# CONFIG_ECHO is not set + +# +# Qualcomm MSM Camera And Video +# + +# +# Camera Sensor Selection +# +# CONFIG_INPUT_GPIO is not set +# CONFIG_POHMELFS is not set + +# +# RAR Register Driver +# +# CONFIG_RAR_REGISTER is not set +# CONFIG_IIO is not set +# CONFIG_RAMZSWAP is not set +# CONFIG_BATMAN_ADV is not set +# CONFIG_STRIP is not set +# CONFIG_FB_SM7XX is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_OBJECTS is not set +CONFIG_DEBUG_SLAB=y +# CONFIG_DEBUG_SLAB_LEAK is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_VM=y +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_DEBUG_SG=y +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_LKDTM is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARM_UNWIND=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL is not set +# CONFIG_OC_ETM is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_TWOFISH_COMMON=y + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y -- 1.6.5.6 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [RFC/PATCH 09/10] [ARM] tegra: harmony: Add harmony board file 2010-03-16 6:41 ` [RFC/PATCH 09/10] [ARM] tegra: harmony: Add harmony board file konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 10/10] [ARM] tegra: Add harmony_defconfig konkers at google.com @ 2010-03-17 8:21 ` Mike Rapoport 2010-03-18 2:27 ` Erik Gilling 1 sibling, 1 reply; 37+ messages in thread From: Mike Rapoport @ 2010-03-17 8:21 UTC (permalink / raw) To: linux-arm-kernel konkers at google.com wrote: > From: Colin Cross <ccross@android.com> > > Signed-off-by: Colin Cross <ccross@android.com> > Signed-off-by: Erik Gilling <konkers@android.com> > --- > arch/arm/mach-tegra/Makefile | 4 + > arch/arm/mach-tegra/board-harmony-panel.c | 75 ++++++++++++++ > arch/arm/mach-tegra/board-harmony-pinmux.c | 144 ++++++++++++++++++++++++++++ > arch/arm/mach-tegra/board-harmony.c | 129 +++++++++++++++++++++++++ > arch/arm/mach-tegra/board-harmony.h | 22 ++++ I think that both panel definition and pinmux can be in the board-harmony.c and thus the board-harmony.h is not needed. > 5 files changed, 374 insertions(+), 0 deletions(-) > create mode 100644 arch/arm/mach-tegra/board-harmony-panel.c > create mode 100644 arch/arm/mach-tegra/board-harmony-pinmux.c > create mode 100644 arch/arm/mach-tegra/board-harmony.c > create mode 100644 arch/arm/mach-tegra/board-harmony.h > > diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile > index 5e47a71..c832aa8 100644 > --- a/arch/arm/mach-tegra/Makefile > +++ b/arch/arm/mach-tegra/Makefile > @@ -9,3 +9,7 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o > obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o > obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o > obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o > + > +obj-${CONFIG_MACH_HARMONY} += board-harmony.o > +obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o > +obj-${CONFIG_MACH_HARMONY} += board-harmony-panel.o > diff --git a/arch/arm/mach-tegra/board-harmony-panel.c b/arch/arm/mach-tegra/board-harmony-panel.c > new file mode 100644 > index 0000000..9fbdacb > --- /dev/null > +++ b/arch/arm/mach-tegra/board-harmony-panel.c > @@ -0,0 +1,75 @@ > +/* > + * arch/arm/mach-tegra/board-harmony-panel.c > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * 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. > + * > + */ > + > +#include <linux/resource.h> > +#include <linux/platform_device.h> > +#include <asm/mach-types.h> > +#include <mach/irqs.h> > +#include <mach/iomap.h> > +#include <mach/tegra_fb.h> > + > +/* Framebuffer */ > +static struct resource fb_resource[] = { > + [0] = { > + .start = INT_DISPLAY_GENERAL, > + .end = INT_DISPLAY_GENERAL, > + .flags = IORESOURCE_IRQ, > + }, > + [1] = { > + .start = TEGRA_DISPLAY_BASE, > + .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1, > + .flags = IORESOURCE_MEM, > + }, > + [2] = { > + .start = 0x1c012000, > + .end = 0x1c012000 + 0x500000 - 1, > + .flags = IORESOURCE_MEM, > + }, > +}; > + > +static struct tegra_fb_lcd_data tegra_fb_lcd_platform_data = { > + .lcd_xres = 1024, > + .lcd_yres = 600, > + .fb_xres = 1024, > + .fb_yres = 600, > + .bits_per_pixel = 16, > +}; > + > +static struct platform_device tegra_fb_device = { > + .name = "tegrafb", > + .id = 0, > + .resource = fb_resource, > + .num_resources = ARRAY_SIZE(fb_resource), > + .dev = { > + .platform_data = &tegra_fb_lcd_platform_data, > + }, > +}; > + > +static int __init harmony_init_panel(void) { > + int ret; > + > + if (!machine_is_harmony()) > + return 0; > + > + ret = platform_device_register(&tegra_fb_device); > + if (ret != 0) > + return ret; > + > + return 0; > +} > + > +device_initcall(harmony_init_panel); > + > diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c > new file mode 100644 > index 0000000..50b15d5 > --- /dev/null > +++ b/arch/arm/mach-tegra/board-harmony-pinmux.c > @@ -0,0 +1,144 @@ > +/* > + * arch/arm/mach-tegra/board-harmony-pinmux.c > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * 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. > + * > + */ > + > +#include <linux/kernel.h> > +#include <mach/pinmux.h> > + > +#include "board-harmony.h" > + > +static struct tegra_pingroup_config harmony_pinmux[] = { > + {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_OSC, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_DTA, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_DTB, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_DTC, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_DTD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_GMD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_GPU, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_KBCB, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_KBCD, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LCSN, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_LSDA, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_LSDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_SDC, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, > + {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > + {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, > +}; > + > +void harmony_pinmux_init(void) > +{ > + tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux)); > +} > diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c > new file mode 100644 > index 0000000..55565a5 > --- /dev/null > +++ b/arch/arm/mach-tegra/board-harmony.c > @@ -0,0 +1,129 @@ > +/* > + * arch/arm/mach-tegra/board-harmony.c > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * 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. > + * > + */ > + > +#include <linux/kernel.h> > +#include <linux/init.h> > +#include <linux/platform_device.h> > +#include <linux/serial_8250.h> > +#include <linux/clk.h> > +#include <linux/dma-mapping.h> > +#include <linux/pda_power.h> > + > +#include <asm/mach-types.h> > +#include <asm/mach/arch.h> > +#include <asm/mach/time.h> > +#include <asm/setup.h> > + > +#include <mach/io.h> > +#include <mach/iomap.h> > +#include <mach/irqs.h> > +#include <mach/iomap.h> > + > +#include "board.h" > +#include "board-harmony.h" > + > +/* NVidia bootloader tags */ > +#define ATAG_NVIDIA 0x41000801 > + > +#define ATAG_NVIDIA_RM 0x1 > +#define ATAG_NVIDIA_DISPLAY 0x2 > +#define ATAG_NVIDIA_FRAMEBUFFER 0x3 > +#define ATAG_NVIDIA_CHIPSHMOO 0x4 > +#define ATAG_NVIDIA_CHIPSHMOOPHYS 0x5 > +#define ATAG_NVIDIA_PRESERVED_MEM_0 0x10000 > +#define ATAG_NVIDIA_PRESERVED_MEM_N 2 > +#define ATAG_NVIDIA_FORCE_32 0x7fffffff > + > +struct tag_tegra { > + __u32 bootarg_key; > + __u32 bootarg_len; > + char bootarg[1]; > +}; > + > +static int __init parse_tag_nvidia(const struct tag *tag) > +{ > + > + return 0; > +} > +__tagtable(ATAG_NVIDIA, parse_tag_nvidia); > + > +static struct plat_serial8250_port debug_uart_platform_data[] = { > + { > + .membase = IO_ADDRESS(TEGRA_UARTD_BASE), > + .mapbase = TEGRA_UARTD_BASE, > + .irq = INT_UARTD, > + .flags = UPF_BOOT_AUTOCONF, > + .iotype = UPIO_MEM, > + .regshift = 2, > + .uartclk = 216000000/16 * 16, > + }, { > + .flags = 0 > + } > +}; > + > +static struct platform_device debug_uart = { > + .name = "serial8250", > + .id = PLAT8250_DEV_PLATFORM, > + .dev = { > + .platform_data = debug_uart_platform_data, > + }, > +}; > + > +static struct platform_device *harmony_devices[] __initdata = { > + &debug_uart, > +}; > + > +static void __init tegra_harmony_fixup(struct machine_desc *desc, struct tag *tags, > + char **cmdline, struct meminfo *mi) > +{ > + mi->nr_banks = 2; > + mi->bank[0].start = PHYS_OFFSET; > + mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET); > + mi->bank[0].size = 448 * SZ_1M; > + mi->bank[1].start = SZ_512M; > + mi->bank[1].node = PHYS_TO_NID(SZ_512M); > + mi->bank[1].size = SZ_512M; > +} > + > +static void __init tegra_harmony_init(void) > +{ > + struct clk *clk; > + > + tegra_common_init(); > + > + clk = clk_get_sys(NULL, "pll_p"); > + clk_enable(clk); > + clk_set_rate(clk, 216000000); > + > + clk = clk_get_sys("uart.3", NULL); > + clk_set_rate(clk, 216000000); > + clk_enable(clk); > + > + harmony_pinmux_init(); > + > + platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices)); > +} > + > +MACHINE_START(HARMONY, "harmony") > + .boot_params = 0x00000100, > + .phys_io = IO_APB_PHYS, > + .io_pg_offst = ((IO_APB_VIRT) >> 18) & 0xfffc, > + .fixup = tegra_harmony_fixup, > + .init_irq = tegra_init_irq, > + .init_machine = tegra_harmony_init, > + .map_io = tegra_map_common_io, > + .timer = &tegra_timer, > +MACHINE_END > diff --git a/arch/arm/mach-tegra/board-harmony.h b/arch/arm/mach-tegra/board-harmony.h > new file mode 100644 > index 0000000..09ca775 > --- /dev/null > +++ b/arch/arm/mach-tegra/board-harmony.h > @@ -0,0 +1,22 @@ > +/* > + * arch/arm/mach-tegra/board-harmony.h > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * 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. > + * > + */ > + > +#ifndef _MACH_TEGRA_BOARD_HARMONY_H > +#define _MACH_TEGRA_BOARD_HARMONY_H > + > +void harmony_pinmux_init(void); > + > +#endif -- Sincerely yours, Mike. ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 09/10] [ARM] tegra: harmony: Add harmony board file 2010-03-17 8:21 ` [RFC/PATCH 09/10] [ARM] tegra: harmony: Add harmony board file Mike Rapoport @ 2010-03-18 2:27 ` Erik Gilling 2010-03-18 20:41 ` mike at compulab.co.il 0 siblings, 1 reply; 37+ messages in thread From: Erik Gilling @ 2010-03-18 2:27 UTC (permalink / raw) To: linux-arm-kernel On Wed, Mar 17, 2010 at 1:21 AM, Mike Rapoport <mike@compulab.co.il> wrote: > > I think that both panel definition and pinmux can be in the board-harmony.c > and thus the board-harmony.h is not needed. In our experience board files get sufficiently cluttered with platform device definitions, callbacks, and fixups that splitting them apart make them much easer to deal with. See the sholes support at http://android.git.kernel.org/?p=kernel/omap.git;a=tree;f=arch/arm/mach-omap2;hb=android-omap-2.6.32 . -Erik ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 09/10] [ARM] tegra: harmony: Add harmony board file 2010-03-18 2:27 ` Erik Gilling @ 2010-03-18 20:41 ` mike at compulab.co.il 0 siblings, 0 replies; 37+ messages in thread From: mike at compulab.co.il @ 2010-03-18 20:41 UTC (permalink / raw) To: linux-arm-kernel On Wed, Mar 17, 2010 at 07:27:04PM -0700, Erik Gilling wrote: > On Wed, Mar 17, 2010 at 1:21 AM, Mike Rapoport <mike@compulab.co.il> wrote: > > > > I think that both panel definition and pinmux can be in the board-harmony.c > > and thus the board-harmony.h is not needed. > > In our experience board files get sufficiently cluttered with platform > device definitions, callbacks, and fixups that splitting them apart > make them much easer to deal with. See the sholes support at > http://android.git.kernel.org/?p=kernel/omap.git;a=tree;f=arch/arm/mach-omap2;hb=android-omap-2.6.32 > . I'm not sure that staring over with several small files for different board features is that necessary. If the board file becomes bloated than it'd make sense to split it. But a board file with three platform device definitions and mux table is not that big... > -Erik -- Sincerely yours, Mike. ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 08/10] [ARM] tegra: Add framebuffer driver 2010-03-16 6:41 ` [RFC/PATCH 08/10] [ARM] tegra: Add framebuffer driver konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 09/10] [ARM] tegra: harmony: Add harmony board file konkers at google.com @ 2010-03-16 7:57 ` Jaya Kumar 2010-03-17 0:31 ` Colin Cross 2010-03-18 8:47 ` Russell King - ARM Linux 2 siblings, 1 reply; 37+ messages in thread From: Jaya Kumar @ 2010-03-16 7:57 UTC (permalink / raw) To: linux-arm-kernel Hi Colin, Erik, Interesting work. I'd recommend CCing linux-fbdev as well in future so that fbdev folks can also get a chance to review your new fbdev driver. On Tue, Mar 16, 2010 at 2:41 PM, <konkers@google.com> wrote: > From: Colin Cross <ccross@android.com> > > Signed-off-by: Colin Cross <ccross@android.com> > Signed-off-by: Erik Gilling <konkers@android.com> > --- > ?arch/arm/mach-tegra/include/mach/tegra_fb.h | ? 24 + > ?drivers/video/Kconfig ? ? ? ? ? ? ? ? ? ? ? | ? 11 + > ?drivers/video/Makefile ? ? ? ? ? ? ? ? ? ? ?| ? ?1 + > ?drivers/video/tegrafb.c ? ? ? ? ? ? ? ? ? ? | ?620 +++++++++++++++++++++++++++ > ?4 files changed, 656 insertions(+), 0 deletions(-) > ?create mode 100644 arch/arm/mach-tegra/include/mach/tegra_fb.h > ?create mode 100644 drivers/video/tegrafb.c > > diff --git a/arch/arm/mach-tegra/include/mach/tegra_fb.h b/arch/arm/mach-tegra/include/mach/tegra_fb.h > new file mode 100644 > index 0000000..f173544 > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/tegra_fb.h > @@ -0,0 +1,24 @@ > +/* > + * arch/arm/mach-tegra/include/mach/tegra_fb.h > + * > + * Copyright (C) 2010 Google, Inc. > + * Author: Colin Cross <ccross@android.com> > + * > + * 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. > + * > + */ > + > +struct tegra_fb_lcd_data { > + ? ? ? int ? ? fb_xres; > + ? ? ? int ? ? fb_yres; > + ? ? ? int ? ? lcd_xres; > + ? ? ? int ? ? lcd_yres; > + ? ? ? int ? ? bits_per_pixel; > +}; I'm trying to understand what's the difference between fb and lcd *res. > diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig > index 5a5c303..b2e68e2 100644 > --- a/drivers/video/Kconfig > +++ b/drivers/video/Kconfig > @@ -1074,6 +1074,17 @@ config FB_RIVA_BACKLIGHT > ? ? ? ?help > ? ? ? ? ?Say Y here if you want to control the backlight of your display. > > +config FB_TEGRA > + ? ? ? tristate "NVIDIA Tegra SoC display support" > + ? ? ? depends on ARCH_TEGRA && FB = y > + ? ? ? select FB_CFB_FILLRECT > + ? ? ? select FB_CFB_COPYAREA > + ? ? ? select FB_CFB_IMAGEBLIT > + ? ? ? default FB > + ? ? ? help > + ? ? ? ? This driver supports the NVIDIA Tegra systems-on-a-chip. ?This > + ? ? ? ? driver can not be compiled as a module. Out of curiosity, why not? > + > ?config FB_I810 > ? ? ? ?tristate "Intel 810/815 support (EXPERIMENTAL)" > ? ? ? ?depends on EXPERIMENTAL && FB && PCI && X86_32 && AGP_INTEL > diff --git a/drivers/video/Makefile b/drivers/video/Makefile > index 4ecb30c..d4a14f2 100644 > --- a/drivers/video/Makefile > +++ b/drivers/video/Makefile > @@ -129,6 +129,7 @@ obj-$(CONFIG_XEN_FBDEV_FRONTEND) ?+= xen-fbfront.o > ?obj-$(CONFIG_FB_CARMINE) ? ? ? ? ?+= carminefb.o > ?obj-$(CONFIG_FB_MB862XX) ? ? ? ? += mb862xx/ > ?obj-$(CONFIG_FB_MSM) ? ? ? ? ? ? ?+= msm/ > +obj-$(CONFIG_FB_TEGRA) ? ? ? ? ? ?+= tegrafb.o > > ?# Platform or fallback drivers go here > ?obj-$(CONFIG_FB_UVESA) ? ? ? ? ? ?+= uvesafb.o > diff --git a/drivers/video/tegrafb.c b/drivers/video/tegrafb.c > new file mode 100644 > index 0000000..634022b > --- /dev/null > +++ b/drivers/video/tegrafb.c > @@ -0,0 +1,620 @@ > +/* > + * drivers/video/tegrafb.c > + * > + * Copyright (C) 2010 Google, Inc. > + * Author: Colin Cross <ccross@android.com> > + * ? ? ? ? Travis Geiselbrecht <travis@palm.com> > + * > + * 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. > + * > + */ > + > +#include <linux/fb.h> > +#include <linux/module.h> > +#include <linux/kernel.h> > +#include <linux/errno.h> > +#include <linux/string.h> > +#include <linux/mm.h> > +#include <linux/slab.h> > +#include <linux/delay.h> > +#include <linux/platform_device.h> > +#include <linux/interrupt.h> > +#include <linux/clk.h> > +#include <linux/wait.h> > +#include <asm/cacheflush.h> > +#include <mach/tegra_fb.h> > + > +#define DEBUG 1 You want to enable Debug by default for everyone? > + > +struct tegra_fb_info { > + ? ? ? struct clk *clk; > + ? ? ? struct resource *reg_mem; > + ? ? ? struct resource *fb_mem; > + ? ? ? void __iomem *reg_base; > + ? ? ? wait_queue_head_t event_wq; > + ? ? ? unsigned int wait_condition; > + ? ? ? int lcd_xres; > + ? ? ? int lcd_yres; > + ? ? ? int irq; > +}; I think a comment about lcd_.res would help us understand what its used for and how it differs from fb_.res. How come it is being duplicated in multiple structures? > +static int tegra_fb_cursor(struct fb_info *info, struct fb_cursor *cursor) > +{ > + ? ? ? return 0; > +} > + > +static int tegra_fb_sync(struct fb_info *info) > +{ > + ? ? ? return 0; > +} Out of curiosity, why populate these functions if they don't do anything? > + > +#ifdef DEBUG > +#define DUMP_REG(a) pr_info("%-32s\t%03x\t%08x\n", #a, a, tegra_fb_readl(tegra_fb, a)); Could pr_debug be useful above? > +static struct fb_ops tegra_fb_ops = { > + ? ? ? .fb_cursor = tegra_fb_cursor, > + ? ? ? .fb_sync = tegra_fb_sync, These 2 were the empty functions from above. I'm guessing this isn't needed. > + > +static int tegra_plat_remove(struct platform_device *pdev) > +{ > + ? ? ? struct fb_info *fb = platform_get_drvdata(pdev); > + ? ? ? struct tegra_fb_info *tegra_fb = fb->par; > + ? ? ? clk_disable(tegra_fb->clk); > + ? ? ? iounmap(fb->screen_base); > + ? ? ? release_resource(tegra_fb->fb_mem); > + ? ? ? iounmap(tegra_fb->reg_base); > + ? ? ? release_resource(tegra_fb->reg_mem); > + ? ? ? framebuffer_release(fb); > + ? ? ? return 0; > +} > + I didn't read through carefully but shouldn't there be an unregister_framebuffer in above? Wouldn't the above cause a free while the structures could still in use by fb*? Thanks, jaya ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 08/10] [ARM] tegra: Add framebuffer driver 2010-03-16 7:57 ` [RFC/PATCH 08/10] [ARM] tegra: Add framebuffer driver Jaya Kumar @ 2010-03-17 0:31 ` Colin Cross 0 siblings, 0 replies; 37+ messages in thread From: Colin Cross @ 2010-03-17 0:31 UTC (permalink / raw) To: linux-arm-kernel (Sorry about the HTML - resending in plain text for the linux-fbdev list) Hi Jaya, thanks for your comments. On Tue, Mar 16, 2010 at 12:57 AM, Jaya Kumar <jayakumar.lkml@gmail.com>wrote: > Hi Colin, Erik, > > Interesting work. > > I'd recommend CCing linux-fbdev as well in future so that fbdev folks > can also get a chance to review your new fbdev driver. Will do > +struct tegra_fb_lcd_data { > > + int fb_xres; > > + int fb_yres; > > + int lcd_xres; > > + int lcd_yres; > > + int bits_per_pixel; > > +}; > > I'm trying to understand what's the difference between fb and lcd *res. fb res is the resolution of the framebuffer driver as seen by userspace. lcd res is the resolution of the screen connected to the Tegra pins. If they are different, the Tegra display block can do scaling on the output. Generally they will be the same. I'll add a comment to the lcd resolution. > > +config FB_TEGRA > > + tristate "NVIDIA Tegra SoC display support" > > + depends on ARCH_TEGRA && FB = y > > + select FB_CFB_FILLRECT > > + select FB_CFB_COPYAREA > > + select FB_CFB_IMAGEBLIT > > + default FB > > + help > > + This driver supports the NVIDIA Tegra systems-on-a-chip. This > > + driver can not be compiled as a module. > > Out of curiosity, why not? > Oversight, the option is tristate, so I'll remove this text. > > +#define DEBUG 1 > > You want to enable Debug by default for everyone? Oops, I'll take it out > > +struct tegra_fb_info { > > + struct clk *clk; > > + struct resource *reg_mem; > > + struct resource *fb_mem; > > + void __iomem *reg_base; > > + wait_queue_head_t event_wq; > > + unsigned int wait_condition; > > + int lcd_xres; > > + int lcd_yres; > > + int irq; > > +}; > > I think a comment about lcd_.res would help us understand what its > used for and how it differs from fb_.res. How come it is being > duplicated in multiple structures? The tegra_fb_lcd_data struct is passed in as platform_data, and used to initialize the state in the tegra_fb_info struct. > +static int tegra_fb_cursor(struct fb_info *info, struct fb_cursor > *cursor) > > +{ > > + return 0; > > +} > > + > > +static int tegra_fb_sync(struct fb_info *info) > > +{ > > + return 0; > > +} > > Out of curiosity, why populate these functions if they don't do anything? They were placeholders, I'll remove them until they get implemented. > > + > > +#ifdef DEBUG > > +#define DUMP_REG(a) pr_info("%-32s\t%03x\t%08x\n", #a, a, > tegra_fb_readl(tegra_fb, a)); > > Could pr_debug be useful above? > The dump_regs function still needs to be inside the #ifdef DEBUG, but I'll change the pr_info to pr_debug to lower the log level. > > +static struct fb_ops tegra_fb_ops = { > > + .fb_cursor = tegra_fb_cursor, > > + .fb_sync = tegra_fb_sync, > > These 2 were the empty functions from above. I'm guessing this isn't > needed. Removed > > + > > +static int tegra_plat_remove(struct platform_device *pdev) > > +{ > > + struct fb_info *fb = platform_get_drvdata(pdev); > > + struct tegra_fb_info *tegra_fb = fb->par; > > + clk_disable(tegra_fb->clk); > > + iounmap(fb->screen_base); > > + release_resource(tegra_fb->fb_mem); > > + iounmap(tegra_fb->reg_base); > > + release_resource(tegra_fb->reg_mem); > > + framebuffer_release(fb); > > + return 0; > > +} > > + > > I didn't read through carefully but shouldn't there be an > unregister_framebuffer in above? Wouldn't the above cause a free while > the structures could still in use by fb*? > Good catch - unregister_framebuffer should be the first call. We generally don't use modules much, so compiling as a module has been tested, but not running as a module. Thanks, Colin ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 08/10] [ARM] tegra: Add framebuffer driver 2010-03-16 6:41 ` [RFC/PATCH 08/10] [ARM] tegra: Add framebuffer driver konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 09/10] [ARM] tegra: harmony: Add harmony board file konkers at google.com 2010-03-16 7:57 ` [RFC/PATCH 08/10] [ARM] tegra: Add framebuffer driver Jaya Kumar @ 2010-03-18 8:47 ` Russell King - ARM Linux 2010-03-18 23:57 ` Colin Cross 2 siblings, 1 reply; 37+ messages in thread From: Russell King - ARM Linux @ 2010-03-18 8:47 UTC (permalink / raw) To: linux-arm-kernel On Mon, Mar 15, 2010 at 11:41:26PM -0700, konkers at google.com wrote: > +static int tegra_fb_set_par(struct fb_info *info) > +{ > + struct tegra_fb_info *tegra_fb = info->par; > + struct fb_var_screeninfo *var = &info->var; > + struct fb_fix_screeninfo *fix = &info->fix; > + u32 color_depth; > + unsigned int h_dda; > + unsigned int v_dda; > + > + /* we only support RGB ordering for now */ > + switch (var->bits_per_pixel) { > + case 32: > + case 24: > + var->red.offset = 0; > + var->red.length = 8; > + var->green.offset = 8; > + var->green.length = 8; > + var->blue.offset = 16; > + var->blue.length = 8; > + color_depth = DC_COLOR_DEPTH_B8G8R8A8; > + break; > + case 16: > + var->red.offset = 11; > + var->red.length = 5; > + var->green.offset = 5; > + var->green.length = 6; > + var->blue.offset = 0; > + var->blue.length = 5; > + color_depth = DC_COLOR_DEPTH_B5G6R5; > + break; > + default: > + return -1; Is this really -EPERM, "Operation not permitted"? Please use a proper errno code rather than just thinking "Oh, I'll use -1 because its easier". ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 08/10] [ARM] tegra: Add framebuffer driver 2010-03-18 8:47 ` Russell King - ARM Linux @ 2010-03-18 23:57 ` Colin Cross 0 siblings, 0 replies; 37+ messages in thread From: Colin Cross @ 2010-03-18 23:57 UTC (permalink / raw) To: linux-arm-kernel On Thu, Mar 18, 2010 at 1:47 AM, Russell King - ARM Linux <linux@arm.linux.org.uk> wrote: > On Mon, Mar 15, 2010 at 11:41:26PM -0700, konkers at google.com wrote: >> +static int tegra_fb_set_par(struct fb_info *info) >> +{ >> + ? ? struct tegra_fb_info *tegra_fb = info->par; >> + ? ? struct fb_var_screeninfo *var = &info->var; >> + ? ? struct fb_fix_screeninfo *fix = &info->fix; >> + ? ? u32 color_depth; >> + ? ? unsigned int h_dda; >> + ? ? unsigned int v_dda; >> + >> + ? ? /* we only support RGB ordering for now */ >> + ? ? switch (var->bits_per_pixel) { >> + ? ? case 32: >> + ? ? case 24: >> + ? ? ? ? ? ? var->red.offset = 0; >> + ? ? ? ? ? ? var->red.length = 8; >> + ? ? ? ? ? ? var->green.offset = 8; >> + ? ? ? ? ? ? var->green.length = 8; >> + ? ? ? ? ? ? var->blue.offset = 16; >> + ? ? ? ? ? ? var->blue.length = 8; >> + ? ? ? ? ? ? color_depth = DC_COLOR_DEPTH_B8G8R8A8; >> + ? ? ? ? ? ? break; >> + ? ? case 16: >> + ? ? ? ? ? ? var->red.offset = 11; >> + ? ? ? ? ? ? var->red.length = 5; >> + ? ? ? ? ? ? var->green.offset = 5; >> + ? ? ? ? ? ? var->green.length = 6; >> + ? ? ? ? ? ? var->blue.offset = 0; >> + ? ? ? ? ? ? var->blue.length = 5; >> + ? ? ? ? ? ? color_depth = DC_COLOR_DEPTH_B5G6R5; >> + ? ? ? ? ? ? break; >> + ? ? default: >> + ? ? ? ? ? ? return -1; > > Is this really -EPERM, "Operation not permitted"? ?Please use a proper > errno code rather than just thinking "Oh, I'll use -1 because its easier". Replaced with -EINVAL Thanks for the review, Colin Cross ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 06/10] [ARM] tegra: add GPIO support 2010-03-16 6:41 ` [RFC/PATCH 06/10] [ARM] tegra: add GPIO support konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 07/10] [ARM] tegra: add pinmux support konkers at google.com @ 2010-03-17 8:15 ` Mike Rapoport 2010-03-18 2:19 ` Erik Gilling 1 sibling, 1 reply; 37+ messages in thread From: Mike Rapoport @ 2010-03-17 8:15 UTC (permalink / raw) To: linux-arm-kernel konkers at google.com wrote: > From: Erik Gilling <konkers@android.com> > > Signed-off-by: Erik Gilling <konkers@android.com> > Signed-off-by: Colin Cross <ccross@android.com> > Cc: Gary King <gking@nvidia.com> > --- > arch/arm/mach-tegra/Kconfig | 1 + > arch/arm/mach-tegra/Makefile | 1 + > arch/arm/mach-tegra/gpio.c | 348 +++++++++++++++++++++++++ > arch/arm/mach-tegra/include/mach/gpio-names.h | 247 ++++++++++++++++++ > arch/arm/mach-tegra/include/mach/gpio.h | 51 ++++ > 5 files changed, 648 insertions(+), 0 deletions(-) > create mode 100644 arch/arm/mach-tegra/gpio.c > create mode 100644 arch/arm/mach-tegra/include/mach/gpio-names.h > create mode 100644 arch/arm/mach-tegra/include/mach/gpio.h > > diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig > index 64ab14f..1ec54d6 100644 > --- a/arch/arm/mach-tegra/Kconfig > +++ b/arch/arm/mach-tegra/Kconfig > @@ -9,6 +9,7 @@ config ARCH_TEGRA_2x_SOC > bool "Tegra 2 family" > select CPU_V7 > select ARM_GIC > + select ARCH_REQUIRE_GPIOLIB > help > Support for NVIDIA Tegra AP20 and T20 processors, based on the > ARM CortexA9MP CPU and the ARM PL310 L2 cache controller > diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile > index 01f47fd..122f7dc 100644 > --- a/arch/arm/mach-tegra/Makefile > +++ b/arch/arm/mach-tegra/Makefile > @@ -3,6 +3,7 @@ obj-y += io.o > obj-y += irq.o > obj-y += clock.o > obj-y += timer.o > +obj-y += gpio.o > obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o > obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o > obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o > diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c > new file mode 100644 > index 0000000..4820e01 > --- /dev/null > +++ b/arch/arm/mach-tegra/gpio.c > @@ -0,0 +1,348 @@ > +/* > + * arch/arm/mach-tegra/gpio.c > + * > + * Copyright (c) 2010 Google, Inc > + * > + * Author: > + * Erik Gilling <konkers@google.com> > + * > + * 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. > + * > + */ > + > +#include <linux/init.h> > +#include <linux/irq.h> > + > +#include <asm/io.h> > +#include <asm/gpio.h> > + > +#include <mach/iomap.h> > + > +#define GPIO_BANK(x) ((x) >> 5) > +#define GPIO_PORT(x) (((x) >> 3) & 0x3) > +#define GPIO_BIT(x) ((x) & 0x7) > + > +#define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \ > + GPIO_BANK(x) * 0x80 + \ > + GPIO_PORT(x) * 4) > + > +#define GPIO_CNF(x) (GPIO_REG(x) + 0x00) > +#define GPIO_OE(x) (GPIO_REG(x) + 0x10) > +#define GPIO_OUT(x) (GPIO_REG(x) + 0X20) > +#define GPIO_IN(x) (GPIO_REG(x) + 0x30) > +#define GPIO_INT_STA(x) (GPIO_REG(x) + 0x40) > +#define GPIO_INT_ENB(x) (GPIO_REG(x) + 0x50) > +#define GPIO_INT_LVL(x) (GPIO_REG(x) + 0x60) > +#define GPIO_INT_CLR(x) (GPIO_REG(x) + 0x70) > + > +#define GPIO_MSK_CNF(x) (GPIO_REG(x) + 0x800) > +#define GPIO_MSK_OE(x) (GPIO_REG(x) + 0x810) > +#define GPIO_MSK_OUT(x) (GPIO_REG(x) + 0X820) > +#define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + 0x840) > +#define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + 0x850) > +#define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + 0x860) > + > +#define GPIO_INT_LVL_MASK 0x010101 > +#define GPIO_INT_LVL_EDGE_RISING 0x000101 > +#define GPIO_INT_LVL_EDGE_FALLING 0x000100 > +#define GPIO_INT_LVL_EDGE_BOTH 0x010100 > +#define GPIO_INT_LVL_LEVEL_HIGH 0x000001 > +#define GPIO_INT_LVL_LEVEL_LOW 0x000000 > + > +struct tegra_gpio_bank { > + int bank; > + int irq; > + spinlock_t lvl_lock[4]; > +}; > + > + > +static struct tegra_gpio_bank tegra_gpio_banks[] = { > + {.bank = 0, .irq = INT_GPIO1}, > + {.bank = 1, .irq = INT_GPIO2}, > + {.bank = 2, .irq = INT_GPIO3}, > + {.bank = 3, .irq = INT_GPIO4}, > + {.bank = 4, .irq = INT_GPIO5}, > + {.bank = 5, .irq = INT_GPIO6}, > + {.bank = 6, .irq = INT_GPIO7}, > +}; > + > +static int tegra_gpio_compose(int bank, int port, int bit) > +{ > + return (bank << 5) | ((port & 0x3) << 3) | (bit & 0x7); > +} > + > +static void tegra_gpio_mask_write(u32 reg, int gpio, int value) > +{ > + u32 val; > + > + val = 0x100 << GPIO_BIT(gpio); > + if (value) > + val |= 1 << GPIO_BIT(gpio); > + __raw_writel(val, reg); > +} > + > +void tegra_gpio_enable(int gpio) > +{ > + tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1); > +} > + > +void tegra_gpio_disable(int gpio) > +{ > + tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0); > +} Can you please elaborate why these two are required? They are not referenced anywhere ... > +static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value) > +{ > + tegra_gpio_mask_write(GPIO_MSK_OUT(offset), offset, value); > +} > + > +static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) > +{ > + return (__raw_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1; > +} > + > +static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset) > +{ > + tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 0); > + return 0; > +} > + > +static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset, > + int value) > +{ > + tegra_gpio_set(chip, offset, value); > + tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 1); > + return 0; > +} > + > + > + > +static struct gpio_chip tegra_gpio_chip = { > + .label = "tegra-gpio", > + .direction_input = tegra_gpio_direction_input, > + .get = tegra_gpio_get, > + .direction_output = tegra_gpio_direction_output, > + .set = tegra_gpio_set, > + .base = 0, > + .ngpio = ARCH_NR_GPIOS, > +}; > + > +static void tegra_gpio_irq_ack(unsigned int irq) > +{ > + int gpio = irq - INT_GPIO_BASE; > + > + __raw_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio)); > +} > + > +static void tegra_gpio_irq_mask(unsigned int irq) > +{ > + int gpio = irq - INT_GPIO_BASE; > + > + tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0); > +} > + > +static void tegra_gpio_irq_unmask(unsigned int irq) > +{ > + int gpio = irq - INT_GPIO_BASE; > + > + tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1); > +} > + > +static int tegra_gpio_irq_set_type(unsigned int irq, unsigned int type) > +{ > + int gpio = irq - INT_GPIO_BASE; > + struct tegra_gpio_bank *bank = get_irq_chip_data(irq); > + int port = GPIO_PORT(gpio); > + int lvl_type; > + int val; > + unsigned long flags; > + > + switch (type) { > + case IRQ_TYPE_EDGE_RISING: > + lvl_type = GPIO_INT_LVL_EDGE_RISING; > + break; > + > + case IRQ_TYPE_EDGE_FALLING: > + lvl_type = GPIO_INT_LVL_EDGE_FALLING; > + break; > + > + case IRQ_TYPE_EDGE_BOTH: > + lvl_type = GPIO_INT_LVL_EDGE_BOTH; > + break; > + > + case IRQ_TYPE_LEVEL_HIGH: > + lvl_type = GPIO_INT_LVL_LEVEL_HIGH; > + break; > + > + case IRQ_TYPE_LEVEL_LOW: > + lvl_type = GPIO_INT_LVL_LEVEL_LOW; > + break; > + > + default: > + return -EINVAL; > + } > + > + spin_lock_irqsave(&bank->lvl_lock[port], flags); > + > + val = __raw_readl(GPIO_INT_LVL(gpio)); > + val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio)); > + val |= lvl_type << GPIO_BIT(gpio); > + __raw_writel(val, GPIO_INT_LVL(gpio)); > + > + spin_unlock_irqrestore(&bank->lvl_lock[port], flags); > + > + if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) > + __set_irq_handler_unlocked(irq, handle_level_irq); > + else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) > + __set_irq_handler_unlocked(irq, handle_edge_irq); > + > + return 0; > +} > + > +static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) > +{ > + struct tegra_gpio_bank *bank; > + int port; > + int pin; > + int unmasked = 0; > + > + desc->chip->ack(irq); > + > + bank = get_irq_data(irq); > + > + for (port = 0; port < 4; port++) { > + int gpio = tegra_gpio_compose(bank->bank, port, 0); > + unsigned long sta = __raw_readl(GPIO_INT_STA(gpio)) & > + __raw_readl(GPIO_INT_ENB(gpio)); > + u32 lvl = __raw_readl(GPIO_INT_LVL(gpio)); > + > + for_each_bit(pin, &sta, 8) { > + __raw_writel(1 << pin, GPIO_INT_CLR(gpio)); > + > + /* if gpio is edge triggered, clear condition > + * before executing the hander so that we don't > + * miss edges > + */ > + if (lvl & (0x100 << pin)) { > + unmasked = 1; > + desc->chip->unmask(irq); > + } > + > + generic_handle_irq(gpio_to_irq(gpio + pin)); > + } > + } > + > + if (!unmasked) > + desc->chip->unmask(irq); > + > +} > + > + > +static struct irq_chip tegra_gpio_irq_chip = { > + .name = "GPIO", > + .ack = tegra_gpio_irq_ack, > + .mask = tegra_gpio_irq_mask, > + .unmask = tegra_gpio_irq_unmask, > + .set_type = tegra_gpio_irq_set_type, > +}; > + > + > +/* This lock class tells lockdep that GPIO irqs are in a different > + * category than their parents, so it won't report false recursion. > + */ > +static struct lock_class_key gpio_lock_class; > + > +static int __init tegra_gpio_init(void) > +{ > + struct tegra_gpio_bank *bank; > + int i; > + int j; > + > + for (i = 0; i < 7; i++) { > + for (j = 0; j < 4; j++) { > + int gpio = tegra_gpio_compose(i, j, 0); > + __raw_writel(0x00, GPIO_INT_ENB(gpio)); > + } > + } > + > + gpiochip_add(&tegra_gpio_chip); > + > + for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + ARCH_NR_GPIOS); i++) { > + bank = &tegra_gpio_banks[GPIO_BANK(irq_to_gpio(i))]; > + > + lockdep_set_class(&irq_desc[i].lock, &gpio_lock_class); > + set_irq_chip_data(i, bank); > + set_irq_chip(i, &tegra_gpio_irq_chip); > + set_irq_handler(i, handle_simple_irq); > + set_irq_flags(i, IRQF_VALID); > + } > + > + for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { > + bank = &tegra_gpio_banks[i]; > + > + set_irq_chained_handler(bank->irq, tegra_gpio_irq_handler); > + set_irq_data(bank->irq, bank); > + > + for (j = 0; j < 4; j++) > + spin_lock_init(&bank->lvl_lock[j]); > + } > + > + return 0; > +} > + > +postcore_initcall(tegra_gpio_init); > + > +#ifdef CONFIG_DEBUG_FS > + > +#include <linux/debugfs.h> > +#include <linux/seq_file.h> > + > +static int dbg_gpio_show(struct seq_file *s, void *unused) > +{ > + int i; > + int j; > + > + for (i = 0; i < 7; i++) { > + for (j = 0; j < 4; j++) { > + int gpio = tegra_gpio_compose(i, j, 0); > + seq_printf(s, "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", > + i, j, > + __raw_readl(GPIO_CNF(gpio)), > + __raw_readl(GPIO_OE(gpio)), > + __raw_readl(GPIO_OUT(gpio)), > + __raw_readl(GPIO_IN(gpio)), > + __raw_readl(GPIO_INT_STA(gpio)), > + __raw_readl(GPIO_INT_ENB(gpio)), > + __raw_readl(GPIO_INT_LVL(gpio))); > + } > + } > + return 0; > +} > + > +static int dbg_gpio_open(struct inode *inode, struct file *file) > +{ > + return single_open(file, dbg_gpio_show, &inode->i_private); > +} > + > +static const struct file_operations debug_fops = { > + .open = dbg_gpio_open, > + .read = seq_read, > + .llseek = seq_lseek, > + .release = single_release, > +}; > + > +static int __init tegra_gpio_debuginit(void) > +{ > + (void) debugfs_create_file("tegra_gpio", S_IRUGO, > + NULL, NULL, &debug_fops); > + return 0; > +} > +late_initcall(tegra_gpio_debuginit); > +#endif > diff --git a/arch/arm/mach-tegra/include/mach/gpio-names.h b/arch/arm/mach-tegra/include/mach/gpio-names.h > new file mode 100644 > index 0000000..f28220a > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/gpio-names.h I'm still not convinced that gpio-names.h is needed, although it may be hadny for board gpio defines. Anyway, I'd put it into arch/arm/mach-tegra rather than arch/arm/mach-tegra/include/mach because it shouldn't be available for anything except arch/arm/mach-tegra. > @@ -0,0 +1,247 @@ > +/* > + * arch/arm/mach-tegra/include/mach/gpio-names.h > + * > + * Copyright (c) 2010 Google, Inc > + * > + * Author: > + * Erik Gilling <konkers@google.com> > + * > + * 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. > + */ > + > +#ifndef __MACH_TEGRA_GPIO_NAMES_H > +#define __MACH_TEGRA_GPIO_NAMES_H > + > +#define TEGRA_GPIO_PA0 0 > +#define TEGRA_GPIO_PA1 1 > +#define TEGRA_GPIO_PA2 2 > +#define TEGRA_GPIO_PA3 3 > +#define TEGRA_GPIO_PA4 4 > +#define TEGRA_GPIO_PA5 5 > +#define TEGRA_GPIO_PA6 6 > +#define TEGRA_GPIO_PA7 7 > +#define TEGRA_GPIO_PB0 8 > +#define TEGRA_GPIO_PB1 9 > +#define TEGRA_GPIO_PB2 10 > +#define TEGRA_GPIO_PB3 11 > +#define TEGRA_GPIO_PB4 12 > +#define TEGRA_GPIO_PB5 13 > +#define TEGRA_GPIO_PB6 14 > +#define TEGRA_GPIO_PB7 15 > +#define TEGRA_GPIO_PC0 16 > +#define TEGRA_GPIO_PC1 17 > +#define TEGRA_GPIO_PC2 18 > +#define TEGRA_GPIO_PC3 19 > +#define TEGRA_GPIO_PC4 20 > +#define TEGRA_GPIO_PC5 21 > +#define TEGRA_GPIO_PC6 22 > +#define TEGRA_GPIO_PC7 23 > +#define TEGRA_GPIO_PD0 24 > +#define TEGRA_GPIO_PD1 25 > +#define TEGRA_GPIO_PD2 26 > +#define TEGRA_GPIO_PD3 27 > +#define TEGRA_GPIO_PD4 28 > +#define TEGRA_GPIO_PD5 29 > +#define TEGRA_GPIO_PD6 30 > +#define TEGRA_GPIO_PD7 31 > +#define TEGRA_GPIO_PE0 32 > +#define TEGRA_GPIO_PE1 33 > +#define TEGRA_GPIO_PE2 34 > +#define TEGRA_GPIO_PE3 35 > +#define TEGRA_GPIO_PE4 36 > +#define TEGRA_GPIO_PE5 37 > +#define TEGRA_GPIO_PE6 38 > +#define TEGRA_GPIO_PE7 39 > +#define TEGRA_GPIO_PF0 40 > +#define TEGRA_GPIO_PF1 41 > +#define TEGRA_GPIO_PF2 42 > +#define TEGRA_GPIO_PF3 43 > +#define TEGRA_GPIO_PF4 44 > +#define TEGRA_GPIO_PF5 45 > +#define TEGRA_GPIO_PF6 46 > +#define TEGRA_GPIO_PF7 47 > +#define TEGRA_GPIO_PG0 48 > +#define TEGRA_GPIO_PG1 49 > +#define TEGRA_GPIO_PG2 50 > +#define TEGRA_GPIO_PG3 51 > +#define TEGRA_GPIO_PG4 52 > +#define TEGRA_GPIO_PG5 53 > +#define TEGRA_GPIO_PG6 54 > +#define TEGRA_GPIO_PG7 55 > +#define TEGRA_GPIO_PH0 56 > +#define TEGRA_GPIO_PH1 57 > +#define TEGRA_GPIO_PH2 58 > +#define TEGRA_GPIO_PH3 59 > +#define TEGRA_GPIO_PH4 60 > +#define TEGRA_GPIO_PH5 61 > +#define TEGRA_GPIO_PH6 62 > +#define TEGRA_GPIO_PH7 63 > +#define TEGRA_GPIO_PI0 64 > +#define TEGRA_GPIO_PI1 65 > +#define TEGRA_GPIO_PI2 66 > +#define TEGRA_GPIO_PI3 67 > +#define TEGRA_GPIO_PI4 68 > +#define TEGRA_GPIO_PI5 69 > +#define TEGRA_GPIO_PI6 70 > +#define TEGRA_GPIO_PI7 71 > +#define TEGRA_GPIO_PJ0 72 > +#define TEGRA_GPIO_PJ1 73 > +#define TEGRA_GPIO_PJ2 74 > +#define TEGRA_GPIO_PJ3 75 > +#define TEGRA_GPIO_PJ4 76 > +#define TEGRA_GPIO_PJ5 77 > +#define TEGRA_GPIO_PJ6 78 > +#define TEGRA_GPIO_PJ7 79 > +#define TEGRA_GPIO_PK0 80 > +#define TEGRA_GPIO_PK1 81 > +#define TEGRA_GPIO_PK2 82 > +#define TEGRA_GPIO_PK3 83 > +#define TEGRA_GPIO_PK4 84 > +#define TEGRA_GPIO_PK5 85 > +#define TEGRA_GPIO_PK6 86 > +#define TEGRA_GPIO_PK7 87 > +#define TEGRA_GPIO_PL0 88 > +#define TEGRA_GPIO_PL1 89 > +#define TEGRA_GPIO_PL2 90 > +#define TEGRA_GPIO_PL3 91 > +#define TEGRA_GPIO_PL4 92 > +#define TEGRA_GPIO_PL5 93 > +#define TEGRA_GPIO_PL6 94 > +#define TEGRA_GPIO_PL7 95 > +#define TEGRA_GPIO_PM0 96 > +#define TEGRA_GPIO_PM1 97 > +#define TEGRA_GPIO_PM2 98 > +#define TEGRA_GPIO_PM3 99 > +#define TEGRA_GPIO_PM4 100 > +#define TEGRA_GPIO_PM5 101 > +#define TEGRA_GPIO_PM6 102 > +#define TEGRA_GPIO_PM7 103 > +#define TEGRA_GPIO_PN0 104 > +#define TEGRA_GPIO_PN1 105 > +#define TEGRA_GPIO_PN2 106 > +#define TEGRA_GPIO_PN3 107 > +#define TEGRA_GPIO_PN4 108 > +#define TEGRA_GPIO_PN5 109 > +#define TEGRA_GPIO_PN6 110 > +#define TEGRA_GPIO_PN7 111 > +#define TEGRA_GPIO_PO0 112 > +#define TEGRA_GPIO_PO1 113 > +#define TEGRA_GPIO_PO2 114 > +#define TEGRA_GPIO_PO3 115 > +#define TEGRA_GPIO_PO4 116 > +#define TEGRA_GPIO_PO5 117 > +#define TEGRA_GPIO_PO6 118 > +#define TEGRA_GPIO_PO7 119 > +#define TEGRA_GPIO_PP0 120 > +#define TEGRA_GPIO_PP1 121 > +#define TEGRA_GPIO_PP2 122 > +#define TEGRA_GPIO_PP3 123 > +#define TEGRA_GPIO_PP4 124 > +#define TEGRA_GPIO_PP5 125 > +#define TEGRA_GPIO_PP6 126 > +#define TEGRA_GPIO_PP7 127 > +#define TEGRA_GPIO_PQ0 128 > +#define TEGRA_GPIO_PQ1 129 > +#define TEGRA_GPIO_PQ2 130 > +#define TEGRA_GPIO_PQ3 131 > +#define TEGRA_GPIO_PQ4 132 > +#define TEGRA_GPIO_PQ5 133 > +#define TEGRA_GPIO_PQ6 134 > +#define TEGRA_GPIO_PQ7 135 > +#define TEGRA_GPIO_PR0 136 > +#define TEGRA_GPIO_PR1 137 > +#define TEGRA_GPIO_PR2 138 > +#define TEGRA_GPIO_PR3 139 > +#define TEGRA_GPIO_PR4 140 > +#define TEGRA_GPIO_PR5 141 > +#define TEGRA_GPIO_PR6 142 > +#define TEGRA_GPIO_PR7 143 > +#define TEGRA_GPIO_PS0 144 > +#define TEGRA_GPIO_PS1 145 > +#define TEGRA_GPIO_PS2 146 > +#define TEGRA_GPIO_PS3 147 > +#define TEGRA_GPIO_PS4 148 > +#define TEGRA_GPIO_PS5 149 > +#define TEGRA_GPIO_PS6 150 > +#define TEGRA_GPIO_PS7 151 > +#define TEGRA_GPIO_PT0 152 > +#define TEGRA_GPIO_PT1 153 > +#define TEGRA_GPIO_PT2 154 > +#define TEGRA_GPIO_PT3 155 > +#define TEGRA_GPIO_PT4 156 > +#define TEGRA_GPIO_PT5 157 > +#define TEGRA_GPIO_PT6 158 > +#define TEGRA_GPIO_PT7 159 > +#define TEGRA_GPIO_PU0 160 > +#define TEGRA_GPIO_PU1 161 > +#define TEGRA_GPIO_PU2 162 > +#define TEGRA_GPIO_PU3 163 > +#define TEGRA_GPIO_PU4 164 > +#define TEGRA_GPIO_PU5 165 > +#define TEGRA_GPIO_PU6 166 > +#define TEGRA_GPIO_PU7 167 > +#define TEGRA_GPIO_PV0 168 > +#define TEGRA_GPIO_PV1 169 > +#define TEGRA_GPIO_PV2 170 > +#define TEGRA_GPIO_PV3 171 > +#define TEGRA_GPIO_PV4 172 > +#define TEGRA_GPIO_PV5 173 > +#define TEGRA_GPIO_PV6 174 > +#define TEGRA_GPIO_PV7 175 > +#define TEGRA_GPIO_PW0 176 > +#define TEGRA_GPIO_PW1 177 > +#define TEGRA_GPIO_PW2 178 > +#define TEGRA_GPIO_PW3 179 > +#define TEGRA_GPIO_PW4 180 > +#define TEGRA_GPIO_PW5 181 > +#define TEGRA_GPIO_PW6 182 > +#define TEGRA_GPIO_PW7 183 > +#define TEGRA_GPIO_PX0 184 > +#define TEGRA_GPIO_PX1 185 > +#define TEGRA_GPIO_PX2 186 > +#define TEGRA_GPIO_PX3 187 > +#define TEGRA_GPIO_PX4 188 > +#define TEGRA_GPIO_PX5 189 > +#define TEGRA_GPIO_PX6 190 > +#define TEGRA_GPIO_PX7 191 > +#define TEGRA_GPIO_PY0 192 > +#define TEGRA_GPIO_PY1 193 > +#define TEGRA_GPIO_PY2 194 > +#define TEGRA_GPIO_PY3 195 > +#define TEGRA_GPIO_PY4 196 > +#define TEGRA_GPIO_PY5 197 > +#define TEGRA_GPIO_PY6 198 > +#define TEGRA_GPIO_PY7 199 > +#define TEGRA_GPIO_PZ0 200 > +#define TEGRA_GPIO_PZ1 201 > +#define TEGRA_GPIO_PZ2 202 > +#define TEGRA_GPIO_PZ3 203 > +#define TEGRA_GPIO_PZ4 204 > +#define TEGRA_GPIO_PZ5 205 > +#define TEGRA_GPIO_PZ6 206 > +#define TEGRA_GPIO_PZ7 207 > +#define TEGRA_GPIO_PAA0 208 > +#define TEGRA_GPIO_PAA1 209 > +#define TEGRA_GPIO_PAA2 210 > +#define TEGRA_GPIO_PAA3 211 > +#define TEGRA_GPIO_PAA4 212 > +#define TEGRA_GPIO_PAA5 213 > +#define TEGRA_GPIO_PAA6 214 > +#define TEGRA_GPIO_PAA7 215 > +#define TEGRA_GPIO_PBB0 216 > +#define TEGRA_GPIO_PBB1 217 > +#define TEGRA_GPIO_PBB2 218 > +#define TEGRA_GPIO_PBB3 219 > +#define TEGRA_GPIO_PBB4 220 > +#define TEGRA_GPIO_PBB5 221 > +#define TEGRA_GPIO_PBB6 222 > +#define TEGRA_GPIO_PBB7 223 > + > +#endif > diff --git a/arch/arm/mach-tegra/include/mach/gpio.h b/arch/arm/mach-tegra/include/mach/gpio.h > new file mode 100644 > index 0000000..871cd10 > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/gpio.h > @@ -0,0 +1,51 @@ > +/* > + * arch/arm/mach-tegra/include/mach/gpio.h > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * Author: > + * Erik Gilling <konkers@google.com> > + * > + * 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. > + * > + */ > + > +#ifndef __MACH_TEGRA_GPIO_H > +#define __MACH_TEGRA_GPIO_H > + > +#include <mach/irqs.h> > + > +#define ARCH_NR_GPIOS INT_GPIO_NR > + > +#include <asm-generic/gpio.h> > +#include <mach/gpio-names.h> gpio-names can be directly included by the board files that use it > +#define gpio_get_value __gpio_get_value > +#define gpio_set_value __gpio_set_value > +#define gpio_cansleep __gpio_cansleep > + > +static inline int gpio_to_irq(unsigned int gpio) > +{ > + if (gpio < ARCH_NR_GPIOS) > + return INT_GPIO_BASE + gpio; > + return -EINVAL; > +} > + > +static inline int irq_to_gpio(unsigned int irq) > +{ > + if ((irq >= INT_GPIO_BASE) && (irq < INT_GPIO_BASE + INT_GPIO_NR)) > + return irq - INT_GPIO_BASE; > + return -EINVAL; > +} > + > +void tegra_gpio_enable(int gpio); > +void tegra_gpio_disable(int gpio); > + > +#endif -- Sincerely yours, Mike. ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 06/10] [ARM] tegra: add GPIO support 2010-03-17 8:15 ` [RFC/PATCH 06/10] [ARM] tegra: add GPIO support Mike Rapoport @ 2010-03-18 2:19 ` Erik Gilling 0 siblings, 0 replies; 37+ messages in thread From: Erik Gilling @ 2010-03-18 2:19 UTC (permalink / raw) To: linux-arm-kernel On Wed, Mar 17, 2010 at 1:15 AM, Mike Rapoport <mike@compulab.co.il> wrote: > konkers at google.com wrote: >> +void tegra_gpio_enable(int gpio) >> +{ >> + ? ? ? tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1); >> +} >> + >> +void tegra_gpio_disable(int gpio) >> +{ >> + ? ? ? tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0); >> +} > > Can you please elaborate why these two are required? They are not referenced > anywhere ... These are needed to switch a pin/pad from peripheral mode to gpio mode. Since tegra does peripheral muxing by pingroup but gpio muxing by pin this does not fit into the pinmux code. It's intended to be used in board files much like pin muxing. >> +++ b/arch/arm/mach-tegra/include/mach/gpio-names.h > > I'm still not convinced that gpio-names.h is needed, although it may be > hadny for board gpio defines. Anyway, I'd put it into arch/arm/mach-tegra > rather than arch/arm/mach-tegra/include/mach because ?it shouldn't be > available for anything except arch/arm/mach-tegra. The tegra architecture does not define GPIOs numerically so treating them as integers has no useful meaning. It's true that these should only be used in the board files. I'll move the file into arch/arm/mach-tegra. -Erik ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 03/10] [ARM] tegra: Add clock support 2010-03-16 6:41 ` [RFC/PATCH 03/10] [ARM] tegra: Add clock support konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 04/10] [ARM] tegra: SMP support konkers at google.com @ 2010-03-18 8:42 ` Russell King - ARM Linux 2010-03-18 23:57 ` Colin Cross 1 sibling, 1 reply; 37+ messages in thread From: Russell King - ARM Linux @ 2010-03-18 8:42 UTC (permalink / raw) To: linux-arm-kernel On Mon, Mar 15, 2010 at 11:41:21PM -0700, konkers at google.com wrote: > From: Colin Cross <ccross@android.com> > > Signed-off-by: Colin Cross <ccross@android.com> > Signed-off-by: Erik Gilling <konkers@android.com> > --- > arch/arm/Kconfig | 1 + > arch/arm/mach-tegra/Makefile | 2 + > arch/arm/mach-tegra/clock.c | 191 +++++++ > arch/arm/mach-tegra/clock.h | 103 ++++ > arch/arm/mach-tegra/common.c | 1 + > arch/arm/mach-tegra/include/mach/clkdev.h | 32 ++ > arch/arm/mach-tegra/tegra2_clocks.c | 837 +++++++++++++++++++++++++++++ > 7 files changed, 1167 insertions(+), 0 deletions(-) > create mode 100644 arch/arm/mach-tegra/clock.c > create mode 100644 arch/arm/mach-tegra/clock.h > create mode 100644 arch/arm/mach-tegra/include/mach/clkdev.h > create mode 100644 arch/arm/mach-tegra/tegra2_clocks.c > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > index 1232104..a5be2d6 100644 > --- a/arch/arm/Kconfig > +++ b/arch/arm/Kconfig > @@ -576,6 +576,7 @@ config ARCH_TEGRA > select GENERIC_CLOCKEVENTS > select GENERIC_GPIO > select HAVE_CLK > + select COMMON_CLKDEV These should be indented using tabs, not spaces. > +/** > + * clk_preinit - initialize any fields in the struct clk before clk init > + * @clk: struct clk * to initialize > + * > + * Initialize any struct clk fields needed before normal clk initialization > + * can run. No return value. > + */ > +void clk_preinit(struct clk *c) > +{ > + c->lock = __SPIN_LOCK_UNLOCKED(c->lock); spin_lock_init(&c->lock); > +int clk_set_parent(struct clk *c, struct clk *parent) > +{ > + unsigned long flags; > + int ret = 0; > + spin_lock_irqsave(&c->lock, flags); > + if (c->ops && c->ops->set_parent) > + ret = c->ops->set_parent(c, parent); > + else > + BUG(); Does this condition really justify crashing the kernel? Why not just return an error? > +int clk_set_rate(struct clk *c, unsigned long rate) > +{ > + int ret = 0; > + unsigned long flags; > + spin_lock_irqsave(&c->lock, flags); > + if (c->ops && c->ops->set_rate) > + ret = c->ops->set_rate(c, rate); > + else > + BUG(); Ditto. > +unsigned long clk_get_rate(struct clk *c) > +{ > + int ret = 0; > + unsigned long flags; > + spin_lock_irqsave(&c->lock, flags); > + if (c->ops && c->ops->get_rate) > + ret = c->ops->get_rate(c); > + else if (c->parent) > + ret = clk_get_rate(c->parent); > + else > + BUG(); Ditto. > +/* PLL Functions */ > +static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate) > +{ > + u32 val; > + unsigned long input_rate; > + const struct clk_pll_table *sel; > + > + pr_debug("%s on clock %s\n", __func__, c->name); > + /* BUG_ON(c->refcnt != 0); */ > + > + input_rate = clk_get_rate(c->parent); > + for (sel = c->pll_table; sel->input_rate != 0; sel++) { > + if (sel->input_rate == input_rate && sel->output_rate == rate) { > + c->n = sel->n; > + c->m = sel->m; > + c->p = sel->p; > + c->cpcon = sel->cpcon; > + val = clk_readl(c->reg + PLL_BASE); > + if (c->flags & PLL_FIXED) > + val |= PLL_BASE_OVERRIDE; > + val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK | > + PLL_BASE_DIVM_MASK); > + val |= (c->m << PLL_BASE_DIVM_SHIFT) | > + (c->n << PLL_BASE_DIVN_SHIFT); > + BUG_ON(c->p > 2); > + if (c->p == 2) > + val |= 1 << PLL_BASE_DIVP_SHIFT; > + clk_writel(val, c->reg + PLL_BASE); > + c->rate = rate; > + > + if (c->flags & PLL_HAS_CPCON) { > + val = c->cpcon << PLL_MISC_CPCON_SHIFT; > + clk_writel(val, c->reg + PLL_MISC); > + } > + return 0; > + } > + } > + return 1; What's this 'return 1' on error and 'return 0' on success? The clk API uses standard Linux error codes, which are negative constants on error. Please use a standard constant from the errno.h headers. ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 03/10] [ARM] tegra: Add clock support 2010-03-18 8:42 ` [RFC/PATCH 03/10] [ARM] tegra: Add clock support Russell King - ARM Linux @ 2010-03-18 23:57 ` Colin Cross 0 siblings, 0 replies; 37+ messages in thread From: Colin Cross @ 2010-03-18 23:57 UTC (permalink / raw) To: linux-arm-kernel On Thu, Mar 18, 2010 at 1:42 AM, Russell King - ARM Linux <linux@arm.linux.org.uk> wrote: > On Mon, Mar 15, 2010 at 11:41:21PM -0700, konkers at google.com wrote: >> From: Colin Cross <ccross@android.com> >> >> Signed-off-by: Colin Cross <ccross@android.com> >> Signed-off-by: Erik Gilling <konkers@android.com> >> --- >> ?arch/arm/Kconfig ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?1 + >> ?arch/arm/mach-tegra/Makefile ? ? ? ? ? ? ?| ? ?2 + >> ?arch/arm/mach-tegra/clock.c ? ? ? ? ? ? ? | ?191 +++++++ >> ?arch/arm/mach-tegra/clock.h ? ? ? ? ? ? ? | ?103 ++++ >> ?arch/arm/mach-tegra/common.c ? ? ? ? ? ? ?| ? ?1 + >> ?arch/arm/mach-tegra/include/mach/clkdev.h | ? 32 ++ >> ?arch/arm/mach-tegra/tegra2_clocks.c ? ? ? | ?837 +++++++++++++++++++++++++++++ >> ?7 files changed, 1167 insertions(+), 0 deletions(-) >> ?create mode 100644 arch/arm/mach-tegra/clock.c >> ?create mode 100644 arch/arm/mach-tegra/clock.h >> ?create mode 100644 arch/arm/mach-tegra/include/mach/clkdev.h >> ?create mode 100644 arch/arm/mach-tegra/tegra2_clocks.c >> >> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig >> index 1232104..a5be2d6 100644 >> --- a/arch/arm/Kconfig >> +++ b/arch/arm/Kconfig >> @@ -576,6 +576,7 @@ config ARCH_TEGRA >> ? ? ? ? ?select GENERIC_CLOCKEVENTS >> ? ? ? ? ?select GENERIC_GPIO >> ? ? ? ? ?select HAVE_CLK >> + ? ? ? ?select COMMON_CLKDEV > > These should be indented using tabs, not spaces. Fixed >> +/** >> + * clk_preinit - initialize any fields in the struct clk before clk init >> + * @clk: struct clk * to initialize >> + * >> + * Initialize any struct clk fields needed before normal clk initialization >> + * can run. ?No return value. >> + */ >> +void clk_preinit(struct clk *c) >> +{ >> + ? ? c->lock = __SPIN_LOCK_UNLOCKED(c->lock); > > ? ? ? ?spin_lock_init(&c->lock); Fixed >> +int clk_set_parent(struct clk *c, struct clk *parent) >> +{ >> + ? ? unsigned long flags; >> + ? ? int ret = 0; >> + ? ? spin_lock_irqsave(&c->lock, flags); >> + ? ? if (c->ops && c->ops->set_parent) >> + ? ? ? ? ? ? ret = c->ops->set_parent(c, parent); >> + ? ? else >> + ? ? ? ? ? ? BUG(); > > Does this condition really justify crashing the kernel? ?Why not just > return an error? Changed to return -ENOSYS >> +int clk_set_rate(struct clk *c, unsigned long rate) >> +{ >> + ? ? int ret = 0; >> + ? ? unsigned long flags; >> + ? ? spin_lock_irqsave(&c->lock, flags); >> + ? ? if (c->ops && c->ops->set_rate) >> + ? ? ? ? ? ? ret = c->ops->set_rate(c, rate); >> + ? ? else >> + ? ? ? ? ? ? BUG(); > > Ditto. > >> +unsigned long clk_get_rate(struct clk *c) >> +{ >> + ? ? int ret = 0; >> + ? ? unsigned long flags; >> + ? ? spin_lock_irqsave(&c->lock, flags); >> + ? ? if (c->ops && c->ops->get_rate) >> + ? ? ? ? ? ? ret = c->ops->get_rate(c); >> + ? ? else if (c->parent) >> + ? ? ? ? ? ? ret = clk_get_rate(c->parent); >> + ? ? else >> + ? ? ? ? ? ? BUG(); > > Ditto. > >> +/* PLL Functions */ >> +static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate) >> +{ >> + ? ? u32 val; >> + ? ? unsigned long input_rate; >> + ? ? const struct clk_pll_table *sel; >> + >> + ? ? pr_debug("%s on clock %s\n", __func__, c->name); >> + ? ? /* BUG_ON(c->refcnt != 0); */ >> + >> + ? ? input_rate = clk_get_rate(c->parent); >> + ? ? for (sel = c->pll_table; sel->input_rate != 0; sel++) { >> + ? ? ? ? ? ? if (sel->input_rate == input_rate && sel->output_rate == rate) { >> + ? ? ? ? ? ? ? ? ? ? c->n = sel->n; >> + ? ? ? ? ? ? ? ? ? ? c->m = sel->m; >> + ? ? ? ? ? ? ? ? ? ? c->p = sel->p; >> + ? ? ? ? ? ? ? ? ? ? c->cpcon = sel->cpcon; >> + ? ? ? ? ? ? ? ? ? ? val = clk_readl(c->reg + PLL_BASE); >> + ? ? ? ? ? ? ? ? ? ? if (c->flags & PLL_FIXED) >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? val |= PLL_BASE_OVERRIDE; >> + ? ? ? ? ? ? ? ? ? ? val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK | >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?PLL_BASE_DIVM_MASK); >> + ? ? ? ? ? ? ? ? ? ? val |= (c->m << PLL_BASE_DIVM_SHIFT) | >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? (c->n << PLL_BASE_DIVN_SHIFT); >> + ? ? ? ? ? ? ? ? ? ? BUG_ON(c->p > 2); >> + ? ? ? ? ? ? ? ? ? ? if (c->p == 2) >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? val |= 1 << PLL_BASE_DIVP_SHIFT; >> + ? ? ? ? ? ? ? ? ? ? clk_writel(val, c->reg + PLL_BASE); >> + ? ? ? ? ? ? ? ? ? ? c->rate = rate; >> + >> + ? ? ? ? ? ? ? ? ? ? if (c->flags & PLL_HAS_CPCON) { >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? val = c->cpcon << PLL_MISC_CPCON_SHIFT; >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? clk_writel(val, c->reg + PLL_MISC); >> + ? ? ? ? ? ? ? ? ? ? } >> + ? ? ? ? ? ? ? ? ? ? return 0; >> + ? ? ? ? ? ? } >> + ? ? } >> + ? ? return 1; > > What's this 'return 1' on error and 'return 0' on ?success? ?The clk API > uses standard Linux error codes, which are negative constants on error. > Please use a standard constant from the errno.h headers. Fixed, along with all the other improper return values in tegra2_clocks.c Thanks for the review, Colin ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 01/10] [ARM] tegra: initial tegra support 2010-03-16 6:41 ` [RFC/PATCH 01/10] [ARM] tegra: initial tegra support konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 02/10] [ARM] tegra: Add IRQ support konkers at google.com @ 2010-03-17 7:57 ` Mike Rapoport 1 sibling, 0 replies; 37+ messages in thread From: Mike Rapoport @ 2010-03-17 7:57 UTC (permalink / raw) To: linux-arm-kernel konkers at google.com wrote: > From: Erik Gilling <konkers@android.com> > > Signed-off-by: Colin Cross <ccross@android.com> > Signed-off-by: Erik Gilling <konkers@android.com> > --- > arch/arm/Kconfig | 13 ++ > arch/arm/Makefile | 1 + > arch/arm/mach-tegra/Kconfig | 53 ++++++ > arch/arm/mach-tegra/Makefile | 2 + > arch/arm/mach-tegra/Makefile.boot | 7 + > arch/arm/mach-tegra/board.h | 32 ++++ > arch/arm/mach-tegra/common.c | 44 +++++ > arch/arm/mach-tegra/include/mach/barriers.h | 30 ++++ > arch/arm/mach-tegra/include/mach/debug-macro.S | 45 +++++ > arch/arm/mach-tegra/include/mach/dma.h | 24 +++ > arch/arm/mach-tegra/include/mach/entry-macro.S | 118 ++++++++++++++ > arch/arm/mach-tegra/include/mach/hardware.h | 24 +++ > arch/arm/mach-tegra/include/mach/io.h | 79 +++++++++ > arch/arm/mach-tegra/include/mach/iomap.h | 204 ++++++++++++++++++++++++ > arch/arm/mach-tegra/include/mach/memory.h | 28 ++++ > arch/arm/mach-tegra/include/mach/nand.h | 54 +++++++ > arch/arm/mach-tegra/include/mach/system.h | 39 +++++ > arch/arm/mach-tegra/include/mach/timex.h | 26 +++ > arch/arm/mach-tegra/include/mach/uncompress.h | 78 +++++++++ > arch/arm/mach-tegra/include/mach/vmalloc.h | 28 ++++ > arch/arm/mach-tegra/io.c | 78 +++++++++ > arch/arm/mm/Kconfig | 2 +- > 22 files changed, 1008 insertions(+), 1 deletions(-) > create mode 100644 arch/arm/mach-tegra/Kconfig > create mode 100644 arch/arm/mach-tegra/Makefile > create mode 100644 arch/arm/mach-tegra/Makefile.boot > create mode 100644 arch/arm/mach-tegra/board.h > create mode 100644 arch/arm/mach-tegra/common.c > create mode 100644 arch/arm/mach-tegra/include/mach/barriers.h > create mode 100644 arch/arm/mach-tegra/include/mach/debug-macro.S > create mode 100644 arch/arm/mach-tegra/include/mach/dma.h > create mode 100644 arch/arm/mach-tegra/include/mach/entry-macro.S > create mode 100644 arch/arm/mach-tegra/include/mach/hardware.h > create mode 100644 arch/arm/mach-tegra/include/mach/io.h > create mode 100644 arch/arm/mach-tegra/include/mach/iomap.h > create mode 100644 arch/arm/mach-tegra/include/mach/memory.h > create mode 100644 arch/arm/mach-tegra/include/mach/nand.h > create mode 100644 arch/arm/mach-tegra/include/mach/system.h > create mode 100644 arch/arm/mach-tegra/include/mach/timex.h > create mode 100644 arch/arm/mach-tegra/include/mach/uncompress.h > create mode 100644 arch/arm/mach-tegra/include/mach/vmalloc.h > create mode 100644 arch/arm/mach-tegra/io.c > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > index 3b18128..1232104 100644 > --- a/arch/arm/Kconfig > +++ b/arch/arm/Kconfig > @@ -570,6 +570,17 @@ config ARCH_NUC93X > Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a > low-power and high performance MPEG-4/JPEG multimedia controller chip. > > +config ARCH_TEGRA > + bool "NVIDIA Tegra" > + select GENERIC_TIME > + select GENERIC_CLOCKEVENTS > + select GENERIC_GPIO > + select HAVE_CLK > + select ARCH_HAS_BARRIERS if CACHE_L2X0 > + help > + This enables support for NVIDIA Tegra based systems (Tegra APX, > + Tegra 6xx and Tegra 2 series). > + > config ARCH_PNX4008 > bool "Philips Nexperia PNX4008 Mobile" > select CPU_ARM926T > @@ -852,6 +863,8 @@ if ARCH_S5PC1XX > source "arch/arm/mach-s5pc100/Kconfig" > endif > > +source "arch/arm/mach-tegra/Kconfig" > + > source "arch/arm/mach-u300/Kconfig" > > source "arch/arm/mach-ux500/Kconfig" > diff --git a/arch/arm/Makefile b/arch/arm/Makefile > index 81f54ca..9f2a5fe 100644 > --- a/arch/arm/Makefile > +++ b/arch/arm/Makefile > @@ -167,6 +167,7 @@ machine-$(CONFIG_ARCH_SA1100) := sa1100 > machine-$(CONFIG_ARCH_SHARK) := shark > machine-$(CONFIG_ARCH_STMP378X) := stmp378x > machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx > +machine-$(CONFIG_ARCH_TEGRA) := tegra > machine-$(CONFIG_ARCH_U300) := u300 > machine-$(CONFIG_ARCH_U8500) := ux500 > machine-$(CONFIG_ARCH_VERSATILE) := versatile > diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig > new file mode 100644 > index 0000000..64ab14f > --- /dev/null > +++ b/arch/arm/mach-tegra/Kconfig > @@ -0,0 +1,53 @@ > +if ARCH_TEGRA > + > +comment "NVIDIA Tegra options" > + > +choice > + prompt "Select Tegra processor family for target system" > + > +config ARCH_TEGRA_2x_SOC > + bool "Tegra 2 family" > + select CPU_V7 > + select ARM_GIC > + help > + Support for NVIDIA Tegra AP20 and T20 processors, based on the > + ARM CortexA9MP CPU and the ARM PL310 L2 cache controller > + > +endchoice > + > + > +choice > + prompt "Select Tegra-based product" > + > +config MACH_HARMONY > + bool "Harmony board" > + help > + Support for nVidia Harmony development platform > + > +endchoice > + > +choice > + prompt "Low-level debug console UART" > + default TEGRA_DEBUG_UART_NONE > + > +config TEGRA_DEBUG_UART_NONE > + bool "None" > + > +config TEGRA_DEBUG_UARTA > + bool "UART-A" > + > +config TEGRA_DEBUG_UARTB > + bool "UART-B" > + > +config TEGRA_DEBUG_UARTC > + bool "UART-C" > + > +config TEGRA_DEBUG_UARTD > + bool "UART-D" > + > +config TEGRA_DEBUG_UARTE > + bool "UART-E" > + > +endchoice > + > +endif > diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile > new file mode 100644 > index 0000000..81f003d > --- /dev/null > +++ b/arch/arm/mach-tegra/Makefile > @@ -0,0 +1,2 @@ > +obj-y += common.o > +obj-y += io.o > diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot > new file mode 100644 > index 0000000..e30ea7c > --- /dev/null > +++ b/arch/arm/mach-tegra/Makefile.boot > @@ -0,0 +1,7 @@ > +zreladdr-$(CONFIG_ARCH_TEGRA_1x_SOC) := 0x00008000 > +params_phys-$(CONFIG_ARCH_TEGRA_1x_SOC) := 0x00000100 > +initrd_phys-$(CONFIG_ARCH_TEGRA_1x_SOC) := 0x00800000 Are there any plans to support Tegra 1? If not, these are not needed > +zreladdr-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00008000 > +params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00000100 > +initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000 > diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h > new file mode 100644 > index 0000000..3d06354 > --- /dev/null > +++ b/arch/arm/mach-tegra/board.h I think "common.h" would be a better name. > @@ -0,0 +1,32 @@ > +/* > + * arch/arm/mach-tegra/board.h > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * Author: > + * Colin Cross <ccross@google.com> > + * Erik Gilling <konkers@google.com> > + * > + * 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. > + * > + */ > + > +#ifndef __MACH_TEGRA_BOARD_H > +#define __MACH_TEGRA_BOARD_H > + > +#include <linux/types.h> > + > +void __init tegra_common_init(void); > +void __init tegra_map_common_io(void); > +void __init tegra_init_irq(void); > +void __init tegra_init_clock(void); > + > +extern struct sys_timer tegra_timer; > +#endif > diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c > new file mode 100644 > index 0000000..20875ee > --- /dev/null > +++ b/arch/arm/mach-tegra/common.c > @@ -0,0 +1,44 @@ > +/* > + * arch/arm/mach-tegra/board-harmony.c > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * Author: > + * Colin Cross <ccross@android.com> > + * > + * 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. > + * > + */ > + > +#include <linux/init.h> > +#include <linux/io.h> > + > +#include <asm/hardware/cache-l2x0.h> > + > +#include <mach/iomap.h> > + > +#include "board.h" > + > +void __init tegra_init_cache(void) > +{ > +#ifdef CONFIG_CACHE_L2X0 > + void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000; > + > + writel(0x331, p + L2X0_TAG_LATENCY_CTRL); > + writel(0x441, p + L2X0_DATA_LATENCY_CTRL); > + > + l2x0_init(p, 0x6C080001, 0x8200c3fe); > +#endif > +} > + > +void __init tegra_common_init(void) > +{ > + tegra_init_cache(); > +} > diff --git a/arch/arm/mach-tegra/include/mach/barriers.h b/arch/arm/mach-tegra/include/mach/barriers.h > new file mode 100644 > index 0000000..cc11517 > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/barriers.h > @@ -0,0 +1,30 @@ > +/* > + * arch/arm/mach-realview/include/mach/barriers.h > + * > + * Copyright (C) 2010 ARM Ltd. > + * Written by Catalin Marinas <catalin.marinas@arm.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. > + * > + * 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 __MACH_BARRIERS_H > +#define __MACH_BARRIERS_H > + > +#include <asm/outercache.h> > + > +#define rmb() dmb() > +#define wmb() do { dsb(); outer_sync(); } while (0) > +#define mb() wmb() > + > +#endif /* __MACH_BARRIERS_H */ > diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S > new file mode 100644 > index 0000000..a4f0b80 > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/debug-macro.S > @@ -0,0 +1,45 @@ > +/* > + * arch/arm/mach-tegra/include/mach/debug-macro.S > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * Author: > + * Colin Cross <ccross@google.com> > + * Erik Gilling <konkers@google.com> > + * > + * 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. > + * > + */ > + > +#include <mach/io.h> > + > + .macro addruart,rx, tmp > + mrc p15, 0, \rx, c1, c0 > + tst \rx, #1 @ MMU enabled? > + ldreq \rx, =IO_APB_PHYS @ physical > + ldrne \rx, =IO_APB_VIRT @ virtual > +#if defined(CONFIG_TEGRA_DEBUG_UART_NONE) > +#error "A debug UART must be selected in the kernel config to use DEBUG_LL" > +#elif defined(CONFIG_TEGRA_DEBUG_UARTA) > + orr \rx, \rx, #0x6000 > +#elif defined(CONFIG_TEGRA_DEBUG_UARTB) > + orr \rx, \rx, #0x6040 > +#elif defined(CONFIG_TEGRA_DEBUG_UARTC) > + orr \rx, \rx, #0x6200 > +#elif defined(CONFIG_TEGRA_DEBUG_UARTD) > + orr \rx, \rx, #0x6300 > +#elif defined(CONFIG_TEGRA_DEBUG_UARTE) > + orr \rx, \rx, #0x6400 > +#endif > + .endm > + > +#define UART_SHIFT 2 > +#include <asm/hardware/debug-8250.S> > + > diff --git a/arch/arm/mach-tegra/include/mach/dma.h b/arch/arm/mach-tegra/include/mach/dma.h > new file mode 100644 > index 0000000..b286386 > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/dma.h > @@ -0,0 +1,24 @@ > +/* > + * arch/arm/mach-tegra/include/mach/dma.h > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * Author: > + * Colin Cross <ccross@google.com> > + * Erik Gilling <konkers@google.com> > + * > + * 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. > + * > + */ Is this empty header required? > +#ifndef __MACH_TEGRA_DMA_H > +#define __MACH_TEGRA_DMA_H > + > +#endif > diff --git a/arch/arm/mach-tegra/include/mach/entry-macro.S b/arch/arm/mach-tegra/include/mach/entry-macro.S > new file mode 100644 > index 0000000..2ba9e5c > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/entry-macro.S > @@ -0,0 +1,118 @@ > +/* arch/arm/mach-tegra/include/mach/entry-macro.S > + * > + * Copyright (C) 2009 Palm, Inc. > + * > + * 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. > + * > + */ > +#include <mach/iomap.h> > +#include <mach/io.h> > + > +#if defined(CONFIG_ARM_GIC) > + > +#include <asm/hardware/gic.h> > + > + /* Uses the GIC interrupt controller built into the cpu */ > +#define ICTRL_BASE (IO_CPU_VIRT + 0x100) > + > + .macro disable_fiq > + .endm > + > + .macro get_irqnr_preamble, base, tmp > + movw \base, #(ICTRL_BASE & 0x0000ffff) > + movt \base, #((ICTRL_BASE & 0xffff0000) >> 16) > + .endm > + > + .macro arch_ret_to_user, tmp1, tmp2 > + .endm > + > + /* > + * The interrupt numbering scheme is defined in the > + * interrupt controller spec. To wit: > + * > + * Interrupts 0-15 are IPI > + * 16-28 are reserved > + * 29-31 are local. We allow 30 to be used for the watchdog. > + * 32-1020 are global > + * 1021-1022 are reserved > + * 1023 is "spurious" (no interrupt) > + * > + * For now, we ignore all local interrupts so only return an interrupt > + * if it's between 30 and 1020. The test_for_ipi routine below will > + * pick up on IPIs. > + * > + * A simple read from the controller will tell us the number of the > + * highest priority enabled interrupt. We then just need to check > + * whether it is in the valid range for an IRQ (30-1020 inclusive). > + */ > + > + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp > + > + /* bits 12-10 = src CPU, 9-0 = int # */ > + ldr \irqstat, [\base, #GIC_CPU_INTACK] > + > + ldr \tmp, =1021 > + > + bic \irqnr, \irqstat, #0x1c00 > + > + cmp \irqnr, #29 > + cmpcc \irqnr, \irqnr > + cmpne \irqnr, \tmp > + cmpcs \irqnr, \irqnr > + > + .endm > + > + /* We assume that irqstat (the raw value of the IRQ acknowledge > + * register) is preserved from the macro above. > + * If there is an IPI, we immediately signal end of interrupt on the > + * controller, since this requires the original irqstat value which > + * we won't easily be able to recreate later. > + */ > + > + .macro test_for_ipi, irqnr, irqstat, base, tmp > + bic \irqnr, \irqstat, #0x1c00 > + cmp \irqnr, #16 > + strcc \irqstat, [\base, #GIC_CPU_EOI] > + cmpcs \irqnr, \irqnr > + .endm > + > + /* As above, this assumes that irqstat and base are preserved.. */ > + > + .macro test_for_ltirq, irqnr, irqstat, base, tmp > + bic \irqnr, \irqstat, #0x1c00 > + mov \tmp, #0 > + cmp \irqnr, #29 > + moveq \tmp, #1 > + streq \irqstat, [\base, #GIC_CPU_EOI] > + cmp \tmp, #0 > + .endm > + > +#else > + /* legacy interrupt controller for AP16 */ > + .macro disable_fiq > + .endm > + > + .macro get_irqnr_preamble, base, tmp > + @ enable imprecise aborts > + cpsie a > + @ EVP base at 0xf010f000 > + mov \base, #0xf0000000 > + orr \base, #0x00100000 > + orr \base, #0x0000f000 > + .endm > + > + .macro arch_ret_to_user, tmp1, tmp2 > + .endm > + > + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp > + ldr \irqnr, [\base, #0x20] @ EVT_IRQ_STS > + cmp \irqnr, #0x80 > + .endm > +#endif > diff --git a/arch/arm/mach-tegra/include/mach/hardware.h b/arch/arm/mach-tegra/include/mach/hardware.h > new file mode 100644 > index 0000000..6014edf > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/hardware.h > @@ -0,0 +1,24 @@ > +/* > + * arch/arm/mach-tegra/include/mach/hardware.h > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * Author: > + * Colin Cross <ccross@google.com> > + * Erik Gilling <konkers@google.com> > + * > + * 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. > + * > + */ > + > +#ifndef __MACH_TEGRA_HARDWARE_H > +#define __MACH_TEGRA_HARDWARE_H > + > +#endif > diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h > new file mode 100644 > index 0000000..35edfc3 > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/io.h > @@ -0,0 +1,79 @@ > +/* > + * arch/arm/mach-tegra/include/mach/io.h > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * Author: > + * Colin Cross <ccross@google.com> > + * Erik Gilling <konkers@google.com> > + * > + * 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. > + * > + */ > + > +#ifndef __MACH_TEGRA_IO_H > +#define __MACH_TEGRA_IO_H > + > +#define IO_SPACE_LIMIT 0xffffffff > + > +/* On TEGRA, many peripherals are very closely packed in > + * two 256MB io windows (that actually only use about 64KB > + * at the start of each). > + * > + * We will just map the first 1MB of each window (to minimize > + * pt entries needed) and provide a macro to transform physical > + * io addresses to an appropriate void __iomem *. > + * > + */ > + > +#define IO_CPU_PHYS 0x50040000 > +#define IO_CPU_VIRT 0xFE000000 > +#define IO_CPU_SIZE SZ_16K > + > +#define IO_PPSB_PHYS 0x60000000 > +#define IO_PPSB_VIRT 0xFE200000 > +#define IO_PPSB_SIZE SZ_1M > + > +#define IO_APB_PHYS 0x70000000 > +#define IO_APB_VIRT 0xFE300000 > +#define IO_APB_SIZE SZ_1M > + > +#define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz))) > +#define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst))) > + > +#define IO_TO_VIRT(n) ( \ > + IO_TO_VIRT_BETWEEN((n), IO_PPSB_PHYS, IO_PPSB_SIZE) ? \ > + IO_TO_VIRT_XLATE((n), IO_PPSB_PHYS, IO_PPSB_VIRT) : \ > + IO_TO_VIRT_BETWEEN((n), IO_APB_PHYS, IO_APB_SIZE) ? \ > + IO_TO_VIRT_XLATE((n), IO_APB_PHYS, IO_APB_VIRT) : \ > + IO_TO_VIRT_BETWEEN((n), IO_CPU_PHYS, IO_CPU_SIZE) ? \ > + IO_TO_VIRT_XLATE((n), IO_CPU_PHYS, IO_CPU_VIRT) : \ > + 0) Many other arhces put similar defines in the mach/hardware.h. I really cannot tell what way is better. Russell, any comment here? > +#ifndef __ASSEMBLER__ > + > +#define __arch_ioremap(p, s, t) tegra_ioremap(p, s, t) > +#define __arch_iounmap(v) tegra_iounmap(v) > + > +void __iomem *tegra_ioremap(unsigned long phys, size_t size, unsigned int type); > +void tegra_iounmap(volatile void __iomem *addr); > + > +#define IO_ADDRESS(n) ((void __iomem *) IO_TO_VIRT(n)) > + > +static inline void __iomem *__io(unsigned long addr) > +{ > + return (void __iomem *)addr; > +} > +#define __io(a) __io(a) > +#define __mem_pci(a) (a) > + > +#endif > + > +#endif > diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h > new file mode 100644 > index 0000000..4814c73 > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/iomap.h > @@ -0,0 +1,204 @@ > +/* > + * arch/arm/mach-tegra/include/mach/iomap.h > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * Author: > + * Colin Cross <ccross@google.com> > + * Erik Gilling <konkers@google.com> > + * > + * 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. > + * > + */ > + > +#ifndef __MACH_TEGRA_IOMAP_H > +#define __MACH_TEGRA_IOMAP_H > + > +#include <mach/io.h> > +#include <asm/sizes.h> > + > +#define TEGRA_ARM_PERIF_BASE 0x50040000 > +#define TEGRA_ARM_PERIF_SIZE SZ_8K > + > +#define TEGRA_ARM_INT_DIST_BASE 0x50041000 > +#define TEGRA_ARM_INT_DIST_SIZE SZ_4K > + > +#define TEGRA_DISPLAY_BASE 0x54200000 > +#define TEGRA_DISPLAY_SIZE SZ_256K > + > +#define TEGRA_DISPLAY2_BASE 0x54240000 > +#define TEGRA_DISPLAY2_SIZE SZ_256K > + > +#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000 > +#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64 > + > +#define TEGRA_SECONDARY_ICTLR_BASE 0x60004100 > +#define TEGRA_SECONDARY_ICTLR_SIZE SZ_64 > + > +#define TEGRA_TERTIARY_ICTLR_BASE 0x60004200 > +#define TEGRA_TERTIARY_ICTLR_SIZE SZ_64 > + > +#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300 > +#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64 > + > +#define TEGRA_TMR1_BASE 0x60005000 > +#define TEGRA_TMR1_SIZE SZ_8 > + > +#define TEGRA_TMR2_BASE 0x60005008 > +#define TEGRA_TMR2_SIZE SZ_8 > + > +#define TEGRA_TMRUS_BASE 0x60005010 > +#define TEGRA_TMRUS_SIZE SZ_64 > + > +#define TEGRA_TMR3_BASE 0x60005050 > +#define TEGRA_TMR3_SIZE SZ_8 > + > +#define TEGRA_TMR4_BASE 0x60005058 > +#define TEGRA_TMR4_SIZE SZ_8 > + > +#define TEGRA_CLK_RESET_BASE 0x60006000 > +#define TEGRA_CLK_RESET_SIZE SZ_4K > + > +#define TEGRA_FLOW_CTRL_BASE 0x60007000 > +#define TEGRA_FLOW_CTRL_SIZE 20 > + > +#define TEGRA_STATMON_BASE 0x6000C4000 > +#define TEGRA_STATMON_SIZE SZ_1K > + > +#define TEGRA_GPIO_BASE 0x6000D000 > +#define TEGRA_GPIO_SIZE SZ_4K > + > +#define TEGRA_EXCEPTION_VECTORS_BASE 0x6000F000 > +#define TEGRA_EXCEPTION_VECTORS_SIZE SZ_4K > + > +#define TEGRA_APB_MISC_BASE 0x70000000 > +#define TEGRA_APB_MISC_SIZE SZ_4K > + > +#define TEGRA_AC97_BASE 0x70002000 > +#define TEGRA_AC97_SIZE SZ_512 > + > +#define TEGRA_SPDIF_BASE 0x70002400 > +#define TEGRA_SPDIF_SIZE SZ_512 > + > +#define TEGRA_I2S1_BASE 0x70002800 > +#define TEGRA_I2S1_SIZE SZ_256 > + > +#define TEGRA_I2S2_BASE 0x70002A00 > +#define TEGRA_I2S2_SIZE SZ_256 > + > +#define TEGRA_UARTA_BASE 0x70006000 > +#define TEGRA_UARTA_SIZE SZ_64 > + > +#define TEGRA_UARTB_BASE 0x70006040 > +#define TEGRA_UARTB_SIZE SZ_64 > + > +#define TEGRA_UARTC_BASE 0x70006200 > +#define TEGRA_UARTC_SIZE SZ_256 > + > +#define TEGRA_UARTD_BASE 0x70006300 > +#define TEGRA_UARTD_SIZE SZ_256 > + > +#define TEGRA_UARTE_BASE 0x70006400 > +#define TEGRA_UARTE_SIZE SZ_256 > + > +#define TEGRA_NAND_BASE 0x70008000 > +#define TEGRA_NAND_SIZE SZ_256 > + > +#define TEGRA_HSMMC_BASE 0x70008500 > +#define TEGRA_HSMMC_SIZE SZ_256 > + > +#define TEGRA_SNOR_BASE 0x70009000 > +#define TEGRA_SNOR_SIZE SZ_4K > + > +#define TEGRA_PWFM_BASE 0x7000A000 > +#define TEGRA_PWFM_SIZE SZ_256 > + > +#define TEGRA_MIPI_BASE 0x7000B000 > +#define TEGRA_MIPI_SIZE SZ_256 > + > +#define TEGRA_I2C_BASE 0x7000C000 > +#define TEGRA_I2C_SIZE SZ_256 > + > +#define TEGRA_TWC_BASE 0x7000C100 > +#define TEGRA_TWC_SIZE SZ_256 > + > +#define TEGRA_SPI_BASE 0x7000C380 > +#define TEGRA_SPI_SIZE 48 > + > +#define TEGRA_I2C2_BASE 0x7000C400 > +#define TEGRA_I2C2_SIZE SZ_256 > + > +#define TEGRA_I2C3_BASE 0x7000C500 > +#define TEGRA_I2C3_SIZE SZ_256 > + > +#define TEGRA_OWR_BASE 0x7000D000 > +#define TEGRA_OWR_SIZE 80 > + > +#define TEGRA_DVC_BASE 0x7000D000 > +#define TEGRA_DVC_SIZE SZ_512 > + > +#define TEGRA_SPI1_BASE 0x7000D400 > +#define TEGRA_SPI1_SIZE SZ_512 > + > +#define TEGRA_SPI2_BASE 0x7000D600 > +#define TEGRA_SPI2_SIZE SZ_512 > + > +#define TEGRA_SPI3_BASE 0x7000D800 > +#define TEGRA_SPI3_SIZE SZ_512 > + > +#define TEGRA_SPI4_BASE 0x7000DA00 > +#define TEGRA_SPI4_SIZE SZ_512 > + > +#define TEGRA_RTC_BASE 0x7000E000 > +#define TEGRA_RTC_SIZE SZ_256 > + > +#define TEGRA_KBC_BASE 0x7000E200 > +#define TEGRA_KBC_SIZE SZ_256 > + > +#define TEGRA_PMC_BASE 0x7000E400 > +#define TEGRA_PMC_SIZE SZ_256 > + > +#define TEGRA_MC_BASE 0x7000F000 > +#define TEGRA_MC_SIZE SZ_1K > + > +#define TEGRA_EMC_BASE 0x7000F400 > +#define TEGRA_EMC_SIZE SZ_1K > + > +#define TEGRA_FUSE_BASE 0x7000F800 > +#define TEGRA_FUSE_SIZE SZ_1K > + > +#define TEGRA_KFUSE_BASE 0x7000FC00 > +#define TEGRA_KFUSE_SIZE SZ_1K > + > +#define TEGRA_CSITE_BASE 0x70040000 > +#define TEGRA_CSITE_SIZE SZ_256K > + > +#define TEGRA_USB_BASE 0xC5000000 > +#define TEGRA_USB_SIZE SZ_16K > + > +#define TEGRA_USB1_BASE 0xC5004000 > +#define TEGRA_USB1_SIZE SZ_16K > + > +#define TEGRA_USB2_BASE 0xC5008000 > +#define TEGRA_USB2_SIZE SZ_16K > + > +#define TEGRA_SDMMC1_BASE 0xC8000000 > +#define TEGRA_SDMMC1_SIZE SZ_512 > + > +#define TEGRA_SDMMC2_BASE 0xC8000200 > +#define TEGRA_SDMMC2_SIZE SZ_512 > + > +#define TEGRA_SDMMC3_BASE 0xC8000400 > +#define TEGRA_SDMMC3_SIZE SZ_512 > + > +#define TEGRA_SDMMC4_BASE 0xC8000600 > +#define TEGRA_SDMMC4_SIZE SZ_512 > + > +#endif > diff --git a/arch/arm/mach-tegra/include/mach/memory.h b/arch/arm/mach-tegra/include/mach/memory.h > new file mode 100644 > index 0000000..6151bab > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/memory.h > @@ -0,0 +1,28 @@ > +/* > + * arch/arm/mach-tegra/include/mach/memory.h > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * Author: > + * Colin Cross <ccross@google.com> > + * Erik Gilling <konkers@google.com> > + * > + * 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. > + * > + */ > + > +#ifndef __MACH_TEGRA_MEMORY_H > +#define __MACH_TEGRA_MEMORY_H > + > +/* physical offset of RAM */ > +#define PHYS_OFFSET UL(0) > + > +#endif > + > diff --git a/arch/arm/mach-tegra/include/mach/nand.h b/arch/arm/mach-tegra/include/mach/nand.h > new file mode 100644 > index 0000000..2d26fec > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/nand.h I think this should be added together with NAND controller driver, rather than in the initial chunk > @@ -0,0 +1,54 @@ > +/* > + * arch/arm/mach-tegra/include/mach/nand.h > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * Author: > + * Colin Cross <ccross@google.com> > + * Dima Zavin <dmitriyz@google.com> > + * > + * 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. > + * > + */ > + > +#ifndef __MACH_TEGRA_NAND_H > +#define __MACH_TEGRA_NAND_H > + > +struct tegra_nand_chip_parms { > + uint8_t vendor_id; > + uint8_t device_id; > + uint32_t flags; > + > + uint32_t capacity; > + > + /* all timing info is in nanoseconds */ > + struct { > + uint32_t trp; > + uint32_t trh; > + uint32_t twp; > + uint32_t twh; > + uint32_t tcs; > + uint32_t twhr; > + uint32_t tcr_tar_trr; > + uint32_t twb; > + uint32_t trp_resp; > + uint32_t tadl; > + } timing; > +}; > + > +struct tegra_nand_platform { > + uint8_t max_chips; > + struct tegra_nand_chip_parms *chip_parms; > + unsigned int nr_chip_parms; > + struct mtd_partition *parts; > + unsigned int nr_parts; > +}; > + > +#endif > diff --git a/arch/arm/mach-tegra/include/mach/system.h b/arch/arm/mach-tegra/include/mach/system.h > new file mode 100644 > index 0000000..84d5d46 > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/system.h > @@ -0,0 +1,39 @@ > +/* > + * arch/arm/mach-tegra/include/mach/system.h > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * Author: > + * Colin Cross <ccross@google.com> > + * Erik Gilling <konkers@google.com> > + * > + * 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. > + * > + */ > + > +#ifndef __MACH_TEGRA_SYSTEM_H > +#define __MACH_TEGRA_SYSTEM_H > + > +#include <mach/hardware.h> > +#include <mach/iomap.h> > + > +static inline void arch_idle(void) > +{ > +} > + > +static inline void arch_reset(char mode, const char *cmd) > +{ > + void __iomem *reset = IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x04); > + u32 reg = readl(reset); > + reg |= 0x04; > + writel(reg, reset); > +} > + > +#endif > diff --git a/arch/arm/mach-tegra/include/mach/timex.h b/arch/arm/mach-tegra/include/mach/timex.h > new file mode 100644 > index 0000000..a44ccbd > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/timex.h > @@ -0,0 +1,26 @@ > +/* > + * arch/arm/mach-tegra/include/mach/timex.h > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * Author: > + * Colin Cross <ccross@google.com> > + * Erik Gilling <konkers@google.com> > + * > + * 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. > + * > + */ > + > +#ifndef __MACH_TEGRA_TIMEX_H > +#define __MACH_TEGRA_TIMEX_H > + > +#define CLOCK_TICK_RATE 1000000 > + > +#endif > diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h > new file mode 100644 > index 0000000..6c4dd81 > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/uncompress.h > @@ -0,0 +1,78 @@ > +/* > + * arch/arm/mach-tegra/include/mach/uncompress.h > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * Author: > + * Colin Cross <ccross@google.com> > + * Erik Gilling <konkers@google.com> > + * > + * 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. > + * > + */ > + > +#ifndef __MACH_TEGRA_UNCOMPRESS_H > +#define __MACH_TEGRA_UNCOMPRESS_H > + > +#include <linux/types.h> > +#include <linux/serial_reg.h> > + > +#include <mach/iomap.h> > + > +#if defined(CONFIG_TEGRA_DEBUG_UARTA) > +#define DEBUG_UART_BASE TEGRA_UARTA_BASE > +#elif defined(CONFIG_TEGRA_DEBUG_UARTB) > +#define DEBUG_UART_BASE TEGRA_UARTB_BASE > +#elif defined(CONFIG_TEGRA_DEBUG_UARTC) > +#define DEBUG_UART_BASE TEGRA_UARTC_BASE > +#elif defined(CONFIG_TEGRA_DEBUG_UARTD) > +#define DEBUG_UART_BASE TEGRA_UARTD_BASE > +#elif defined(CONFIG_TEGRA_DEBUG_UARTE) > +#define DEBUG_UART_BASE TEGRA_UARTE_BASE > +#else > +#define DEBUG_UART_BASE NULL > +#endif > + > +static void putc(int c) > +{ > + volatile u8 *uart = (volatile u8 *)DEBUG_UART_BASE; > + int shift = 2; > + > + if (uart == NULL) > + return; > + > + while (!(uart[UART_LSR << shift] & UART_LSR_THRE)) > + barrier(); > + uart[UART_TX << shift] = c; > +} > + > +static inline void flush(void) > +{ > +} > + > +static inline void arch_decomp_setup(void) > +{ > + volatile u8 *uart = (volatile u8 *)DEBUG_UART_BASE; > + int shift = 2; > + > + if (uart == NULL) > + return; > + > + uart[UART_LCR << shift] |= UART_LCR_DLAB; > + uart[UART_DLL << shift] = 0x75; > + uart[UART_DLM << shift] = 0x0; > + uart[UART_LCR << shift] = 3; > +} > + > +static inline void arch_decomp_wdog(void) > +{ > +} > + > +#endif > diff --git a/arch/arm/mach-tegra/include/mach/vmalloc.h b/arch/arm/mach-tegra/include/mach/vmalloc.h > new file mode 100644 > index 0000000..267a141 > --- /dev/null > +++ b/arch/arm/mach-tegra/include/mach/vmalloc.h > @@ -0,0 +1,28 @@ > +/* > + * arch/arm/mach-tegra/include/mach/vmalloc.h > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * Author: > + * Colin Cross <ccross@google.com> > + * Erik Gilling <konkers@google.com> > + * > + * 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. > + * > + */ > + > +#ifndef __MACH_TEGRA_VMALLOC_H > +#define __MACH_TEGRA_VMALLOC_H > + > +#include <asm/sizes.h> > + > +#define VMALLOC_END 0xFE000000 > + > +#endif > diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c > new file mode 100644 > index 0000000..34f88db > --- /dev/null > +++ b/arch/arm/mach-tegra/io.c > @@ -0,0 +1,78 @@ > +/* > + * arch/arm/mach-tegra/io.c > + * > + * Copyright (C) 2010 Google, Inc. > + * > + * Author: > + * Colin Cross <ccross@google.com> > + * Erik Gilling <konkers@google.com> > + * > + * 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. > + * > + */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/init.h> > +#include <linux/mm.h> > + > +#include <mach/hardware.h> > +#include <asm/io.h> > +#include <asm/page.h> > +#include <asm/mach/map.h> > + > +#include "board.h" > + > +static struct map_desc tegra_io_desc[] __initdata = { > + { > + .virtual = IO_PPSB_VIRT, > + .pfn = __phys_to_pfn(IO_PPSB_PHYS), > + .length = IO_PPSB_SIZE, > + .type = MT_DEVICE, > + }, > + { > + .virtual = IO_APB_VIRT, > + .pfn = __phys_to_pfn(IO_APB_PHYS), > + .length = IO_APB_SIZE, > + .type = MT_DEVICE, > + }, > + { > + .virtual = IO_CPU_VIRT, > + .pfn = __phys_to_pfn(IO_CPU_PHYS), > + .length = IO_CPU_SIZE, > + .type = MT_DEVICE, > + }, > +}; > + > +void __init tegra_map_common_io(void) > +{ > + iotable_init(tegra_io_desc, ARRAY_SIZE(tegra_io_desc)); > +} > + > +/* > + * Intercept ioremap() requests for addresses in our fixed mapping regions. > + */ > +void __iomem *tegra_ioremap(unsigned long p, size_t size, unsigned int type) > +{ > + void __iomem *v = IO_ADDRESS(p); > + if (v == NULL) > + v = __arm_ioremap(p, size, type); > + return v; > +} > +EXPORT_SYMBOL(tegra_ioremap); > + > +void tegra_iounmap(volatile void __iomem *addr) > +{ > + unsigned long virt = (unsigned long)addr; > + > + if (virt >= VMALLOC_START && virt < VMALLOC_END) > + __iounmap(addr); > +} > +EXPORT_SYMBOL(tegra_iounmap); > diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig > index c4ed9f9..84b5be3 100644 > --- a/arch/arm/mm/Kconfig > +++ b/arch/arm/mm/Kconfig > @@ -754,7 +754,7 @@ config CACHE_FEROCEON_L2_WRITETHROUGH > config CACHE_L2X0 > bool "Enable the L2x0 outer cache controller" > depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ > - REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4 > + REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4 || ARCH_TEGRA > default y > select OUTER_CACHE > help -- Sincerely yours, Mike. ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 00/10] Tegra2 support 2010-03-16 6:41 ` [RFC/PATCH 00/10] Tegra2 support konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 01/10] [ARM] tegra: initial tegra support konkers at google.com @ 2010-03-18 8:32 ` Russell King - ARM Linux 2010-03-18 16:40 ` Erik Gilling 2010-03-18 20:30 ` Erik Gilling 1 sibling, 2 replies; 37+ messages in thread From: Russell King - ARM Linux @ 2010-03-18 8:32 UTC (permalink / raw) To: linux-arm-kernel On Mon, Mar 15, 2010 at 11:41:18PM -0700, konkers at google.com wrote: > Here's the cleaned up patch stack as promised. We've incorporated the feedback > from Gary and Russel. > > I've pushed these patches to the linux-tegra-2.6.34-rc1 branch at > git://android.git.kernel.org/kernel/tegra.git Please change all the mach/io.h and asm/io.h to linux/io.h, and mach/gpio.h and asm/gpio.h to linux/gpio.h. ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 00/10] Tegra2 support 2010-03-18 8:32 ` [RFC/PATCH 00/10] Tegra2 support Russell King - ARM Linux @ 2010-03-18 16:40 ` Erik Gilling 2010-03-18 20:30 ` Erik Gilling 1 sibling, 0 replies; 37+ messages in thread From: Erik Gilling @ 2010-03-18 16:40 UTC (permalink / raw) To: linux-arm-kernel On Thu, Mar 18, 2010 at 1:32 AM, Russell King - ARM Linux <linux@arm.linux.org.uk> wrote: > On Mon, Mar 15, 2010 at 11:41:18PM -0700, konkers at google.com wrote: >> Here's the cleaned up patch stack as promised. ?We've incorporated the feedback >> from Gary and Russel. >> >> I've pushed these patches to the linux-tegra-2.6.34-rc1 branch at >> git://android.git.kernel.org/kernel/tegra.git > > Please change all the mach/io.h and asm/io.h to linux/io.h, and mach/gpio.h > and asm/gpio.h to linux/gpio.h. Thanks, Will do. -Erik ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 00/10] Tegra2 support 2010-03-18 8:32 ` [RFC/PATCH 00/10] Tegra2 support Russell King - ARM Linux 2010-03-18 16:40 ` Erik Gilling @ 2010-03-18 20:30 ` Erik Gilling 2010-03-18 21:03 ` Erik Gilling 1 sibling, 1 reply; 37+ messages in thread From: Erik Gilling @ 2010-03-18 20:30 UTC (permalink / raw) To: linux-arm-kernel On Thu, Mar 18, 2010 at 1:32 AM, Russell King - ARM Linux <linux@arm.linux.org.uk> wrote: > On Mon, Mar 15, 2010 at 11:41:18PM -0700, konkers at google.com wrote: >> Here's the cleaned up patch stack as promised. ?We've incorporated the feedback >> from Gary and Russel. >> >> I've pushed these patches to the linux-tegra-2.6.34-rc1 branch at >> git://android.git.kernel.org/kernel/tegra.git > > Please change all the mach/io.h and asm/io.h to linux/io.h, and mach/gpio.h > and asm/gpio.h to linux/gpio.h. I assume I want to use asm/io.h in entry-macro.S and debug-macro.S, yes? -Erik ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH 00/10] Tegra2 support 2010-03-18 20:30 ` Erik Gilling @ 2010-03-18 21:03 ` Erik Gilling 0 siblings, 0 replies; 37+ messages in thread From: Erik Gilling @ 2010-03-18 21:03 UTC (permalink / raw) To: linux-arm-kernel On Thu, Mar 18, 2010 at 1:30 PM, Erik Gilling <konkers@google.com> wrote: > On Thu, Mar 18, 2010 at 1:32 AM, Russell King - ARM Linux > <linux@arm.linux.org.uk> wrote: >> On Mon, Mar 15, 2010 at 11:41:18PM -0700, konkers at google.com wrote: >>> Here's the cleaned up patch stack as promised. ?We've incorporated the feedback >>> from Gary and Russel. >>> >>> I've pushed these patches to the linux-tegra-2.6.34-rc1 branch at >>> git://android.git.kernel.org/kernel/tegra.git >> >> Please change all the mach/io.h and asm/io.h to linux/io.h, and mach/gpio.h >> and asm/gpio.h to linux/gpio.h. > > I assume I want to use asm/io.h in entry-macro.S and debug-macro.S, yes? Nevermind. I, apparently, misunderstand what include/asm is used for. I thought it was for files safe to include in assembly. asm/io.h is clearly not. It seems I need to use mach/io.h in these two files. -Erik ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH] ARM: add Tegra support 2010-03-15 22:38 ` Erik Gilling 2010-03-16 6:41 ` [RFC/PATCH 00/10] Tegra2 support konkers at google.com @ 2010-03-16 8:49 ` Mike Rapoport 2010-03-16 13:44 ` Brian Swetland 1 sibling, 1 reply; 37+ messages in thread From: Mike Rapoport @ 2010-03-16 8:49 UTC (permalink / raw) To: linux-arm-kernel Erik Gilling wrote: > On Tue, Mar 9, 2010 at 9:38 AM, Mike Rapoport <mike@compulab.co.il> wrote: >> This patch adds basic support for Nvidia Tegra2 platform. > > This code seems to be our port from > git://android.git.kernel.org/kernel/tegra.git with some features > removed, minor cleanups, and many trivial changes. These changes make > it difficult for us to track improvements and bug fixes in either > direction. Neither Nvidia nor Google showed any movements towards the mainline and it was completely not clear if such plans exist at all. I've posted the patch a week ago and there were no comments from you since then. I'd be glad to see Tegra support in the mainline whether it'd be my patch or yours. I did my best to bring the basic Tegra support to a state that it can be merged into the mainline and I'll be happy to contribute to that support in the future. > We're happy that other people are interested in our work > however are disappointed that our opinions were not sought before > making these changes and posting nor was any attribution given to the > work's authors. My apologies. Indeed, I should have make it clear that my work is based on git://android.git.kernel.org/kernel/tegra.git > We're still in the process here at Google of cleaning up the port for > submission. We should have our changes rebased on 34-rc1 without the > android-common code by the end of the day. We've been maintaining a > patchstack which separates out the functional subsystems. Would > people here prefer to see that or a collapsed patch like this one. > > Specific issues with this patch with respect to our work: > > Lots of trival changes like moving files around, renaming variables, I've moved the things around because in my opinion they belong to the places were I've put them. > and re-wording/re-formating comments (sometimes changing the meaning > of the comment incorrectly) You are little bit exaggerating here. The wording was changed only in one comment and it doesn't seam to me to change the meaning. > Removal of SMP, L2 cache, and pinmux support. I've intended to add SMP, L2 and pinmux after the first hunk would be merged. > Removal of the gpio_names header. Because tegra does not define GPIOs > numerically, it is impossible to convert a gpio name (i.e. PN6) from a > schematic to a GPIO number without consulting and interpreting the > datasheet. The gpio_names header could have been added later, although I don't agree that it is essential to have it at all. Usually board file create their own defines for GPIOs that reflect actual GPIO usage, e.g. SOME_DEVICE_RST. > Removal of the tegra_gpio_enable and tegra_gpio_disable functions. > Because of the way pin muxing is implemented in tegra, gpio > configuration does not map into the pinmuxing subsystem. I've removed these functions because they were not referenced by any other code. > Removal of pr_debug lines from the clock code. I don't think that keeping pr_debug in each function is really good idea. > Changing the way peripheral clocks are defined to use two separate > tables which are required to be kept in sync by hand. Having static clocks definition has its advantages. It simplifies the initialization code and saves several CPU cycles on boot. However, I agree that your approach may be better from the maintainability POV. > Removal of some pll entries. The plls were reordered, but I think none was removed. > -Erik -- Sincerely yours, Mike. ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH] ARM: add Tegra support 2010-03-16 8:49 ` [RFC/PATCH] ARM: add Tegra support Mike Rapoport @ 2010-03-16 13:44 ` Brian Swetland 2010-03-16 14:11 ` Mike Rapoport 0 siblings, 1 reply; 37+ messages in thread From: Brian Swetland @ 2010-03-16 13:44 UTC (permalink / raw) To: linux-arm-kernel On Tue, Mar 16, 2010 at 1:49 AM, Mike Rapoport <mike@compulab.co.il> wrote: > Erik Gilling wrote: >> >> On Tue, Mar 9, 2010 at 9:38 AM, Mike Rapoport <mike@compulab.co.il> wrote: >>> >>> This patch adds basic support for Nvidia Tegra2 platform. >> >> This code seems to be our port from >> git://android.git.kernel.org/kernel/tegra.git with some features >> removed, minor cleanups, and many trivial changes. ?These changes make >> it difficult for us to track improvements and bug fixes in either >> direction. > > Neither Nvidia nor Google showed any movements towards the mainline and > it was completely not clear if such plans exist at all. I've posted the > patch a week ago and there were no comments from you since then. It does help if you cc the authors when sending revised patches out for commentary (as git-send-email does by default, etc), since it's easy to miss things on high traffic lists like lkml or lakml. We first noticed the patch you sent out late Sunday evening, and Erik sent a reply out the following afternoon. Brian ^ permalink raw reply [flat|nested] 37+ messages in thread
* [RFC/PATCH] ARM: add Tegra support 2010-03-16 13:44 ` Brian Swetland @ 2010-03-16 14:11 ` Mike Rapoport 0 siblings, 0 replies; 37+ messages in thread From: Mike Rapoport @ 2010-03-16 14:11 UTC (permalink / raw) To: linux-arm-kernel Hi Brian, Brian Swetland wrote: > On Tue, Mar 16, 2010 at 1:49 AM, Mike Rapoport <mike@compulab.co.il> wrote: >> Erik Gilling wrote: >>> On Tue, Mar 9, 2010 at 9:38 AM, Mike Rapoport <mike@compulab.co.il> wrote: >>>> This patch adds basic support for Nvidia Tegra2 platform. >>> This code seems to be our port from >>> git://android.git.kernel.org/kernel/tegra.git with some features >>> removed, minor cleanups, and many trivial changes. These changes make >>> it difficult for us to track improvements and bug fixes in either >>> direction. >> Neither Nvidia nor Google showed any movements towards the mainline and >> it was completely not clear if such plans exist at all. I've posted the >> patch a week ago and there were no comments from you since then. > > It does help if you cc the authors when sending revised patches out > for commentary (as git-send-email does by default, etc), since it's > easy to miss things on high traffic lists like lkml or lakml. We > first noticed the patch you sent out late Sunday evening, and Erik > sent a reply out the following afternoon. Agree. I should have cc'ed Eric and Colin. Still, I'd expect more constructive comments than those Eric has sent. > Brian -- Sincerely yours, Mike. ^ permalink raw reply [flat|nested] 37+ messages in thread
end of thread, other threads:[~2010-03-18 23:57 UTC | newest] Thread overview: 37+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-03-09 16:38 [RFC/PATCH] ARM: add Tegra support Mike Rapoport 2010-03-14 6:51 ` Mike Rapoport 2010-03-15 6:54 ` Thierry Reding 2010-03-15 16:16 ` Thierry Reding 2010-03-15 17:41 ` Gary King 2010-03-15 18:09 ` Russell King - ARM Linux 2010-03-15 22:38 ` Erik Gilling 2010-03-16 6:41 ` [RFC/PATCH 00/10] Tegra2 support konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 01/10] [ARM] tegra: initial tegra support konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 02/10] [ARM] tegra: Add IRQ support konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 03/10] [ARM] tegra: Add clock support konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 04/10] [ARM] tegra: SMP support konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 05/10] [ARM] tegra: Add timer support konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 06/10] [ARM] tegra: add GPIO support konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 07/10] [ARM] tegra: add pinmux support konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 08/10] [ARM] tegra: Add framebuffer driver konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 09/10] [ARM] tegra: harmony: Add harmony board file konkers at google.com 2010-03-16 6:41 ` [RFC/PATCH 10/10] [ARM] tegra: Add harmony_defconfig konkers at google.com 2010-03-17 8:21 ` [RFC/PATCH 09/10] [ARM] tegra: harmony: Add harmony board file Mike Rapoport 2010-03-18 2:27 ` Erik Gilling 2010-03-18 20:41 ` mike at compulab.co.il 2010-03-16 7:57 ` [RFC/PATCH 08/10] [ARM] tegra: Add framebuffer driver Jaya Kumar 2010-03-17 0:31 ` Colin Cross 2010-03-18 8:47 ` Russell King - ARM Linux 2010-03-18 23:57 ` Colin Cross 2010-03-17 8:15 ` [RFC/PATCH 06/10] [ARM] tegra: add GPIO support Mike Rapoport 2010-03-18 2:19 ` Erik Gilling 2010-03-18 8:42 ` [RFC/PATCH 03/10] [ARM] tegra: Add clock support Russell King - ARM Linux 2010-03-18 23:57 ` Colin Cross 2010-03-17 7:57 ` [RFC/PATCH 01/10] [ARM] tegra: initial tegra support Mike Rapoport 2010-03-18 8:32 ` [RFC/PATCH 00/10] Tegra2 support Russell King - ARM Linux 2010-03-18 16:40 ` Erik Gilling 2010-03-18 20:30 ` Erik Gilling 2010-03-18 21:03 ` Erik Gilling 2010-03-16 8:49 ` [RFC/PATCH] ARM: add Tegra support Mike Rapoport 2010-03-16 13:44 ` Brian Swetland 2010-03-16 14:11 ` Mike Rapoport
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).