* [PATCH v4 02/13] tegra: switch to proper CPU type
2013-04-10 9:14 [PATCH v4 01/13] tegra: pull in iomap.h from the Linux kernel Lucas Stach
@ 2013-04-10 9:14 ` Lucas Stach
2013-04-10 9:14 ` [PATCH v4 03/13] tegra: unify spelling in Kconfig with Linux kernel Lucas Stach
` (10 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Lucas Stach @ 2013-04-10 9:14 UTC (permalink / raw)
To: barebox
Tegras main CPUs are all ARMv7.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
arch/arm/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bb9b47b..dfb7e24 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -137,7 +137,7 @@ config ARCH_VEXPRESS
config ARCH_TEGRA
bool "Nvidia Tegra-based boards"
- select CPU_ARM926T
+ select CPU_V7
select HAS_DEBUG_LL
config ARCH_ZYNQ
--
1.8.1.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v4 03/13] tegra: unify spelling in Kconfig with Linux kernel
2013-04-10 9:14 [PATCH v4 01/13] tegra: pull in iomap.h from the Linux kernel Lucas Stach
2013-04-10 9:14 ` [PATCH v4 02/13] tegra: switch to proper CPU type Lucas Stach
@ 2013-04-10 9:14 ` Lucas Stach
2013-04-10 9:14 ` [PATCH v4 04/13] tegra: introduce Tegra 20 SoC type Lucas Stach
` (9 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Lucas Stach @ 2013-04-10 9:14 UTC (permalink / raw)
To: barebox
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
arch/arm/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index dfb7e24..befed5d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -136,7 +136,7 @@ config ARCH_VEXPRESS
select COMMON_CLK
config ARCH_TEGRA
- bool "Nvidia Tegra-based boards"
+ bool "NVIDIA Tegra"
select CPU_V7
select HAS_DEBUG_LL
--
1.8.1.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v4 04/13] tegra: introduce Tegra 20 SoC type
2013-04-10 9:14 [PATCH v4 01/13] tegra: pull in iomap.h from the Linux kernel Lucas Stach
2013-04-10 9:14 ` [PATCH v4 02/13] tegra: switch to proper CPU type Lucas Stach
2013-04-10 9:14 ` [PATCH v4 03/13] tegra: unify spelling in Kconfig with Linux kernel Lucas Stach
@ 2013-04-10 9:14 ` Lucas Stach
2013-04-10 9:14 ` [PATCH v4 05/13] tegra: move default textbase Lucas Stach
` (8 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Lucas Stach @ 2013-04-10 9:14 UTC (permalink / raw)
To: barebox
Tegra isn't a single architecture, but a collection of more or less
similar chip families. Introduce the same conf define as used in the
Linux kernel to differentiate between those families.
Currently we are only supporting the Tegra20 chip type.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
arch/arm/mach-tegra/Kconfig | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index eda786b..f91267f 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -1,11 +1,23 @@
if ARCH_TEGRA
+choice
+ prompt "Tegra processor type"
+
+config ARCH_TEGRA_2x_SOC
+ bool "Tegra 20"
+
+endchoice
+
+# ---------------------------------------------------------
+
+if ARCH_TEGRA_2x_SOC
+
config ARCH_TEXT_BASE
hex
default 0x31fc0000
choice
- prompt "Tegra Board Type"
+ prompt "Tegra 20 Board Type"
config MACH_TOSHIBA_AC100
bool "Toshiba AC100"
@@ -16,4 +28,8 @@ endchoice
source arch/arm/boards/toshiba-ac100/Kconfig
+endif #ARCH_TEGRA_2x_SOC
+
+# ---------------------------------------------------------
+
endif
--
1.8.1.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v4 05/13] tegra: move default textbase
2013-04-10 9:14 [PATCH v4 01/13] tegra: pull in iomap.h from the Linux kernel Lucas Stach
` (2 preceding siblings ...)
2013-04-10 9:14 ` [PATCH v4 04/13] tegra: introduce Tegra 20 SoC type Lucas Stach
@ 2013-04-10 9:14 ` Lucas Stach
2013-04-10 9:14 ` [PATCH v4 06/13] tegra: switch to DT only Lucas Stach
` (7 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Lucas Stach @ 2013-04-10 9:14 UTC (permalink / raw)
To: barebox
All available opensource tools and published BCT configurations use
0x10800 as the default textbase on Tegra 20.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
arch/arm/mach-tegra/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index f91267f..2f15b27 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -14,7 +14,7 @@ if ARCH_TEGRA_2x_SOC
config ARCH_TEXT_BASE
hex
- default 0x31fc0000
+ default 0x00108000
choice
prompt "Tegra 20 Board Type"
--
1.8.1.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v4 06/13] tegra: switch to DT only
2013-04-10 9:14 [PATCH v4 01/13] tegra: pull in iomap.h from the Linux kernel Lucas Stach
` (3 preceding siblings ...)
2013-04-10 9:14 ` [PATCH v4 05/13] tegra: move default textbase Lucas Stach
@ 2013-04-10 9:14 ` Lucas Stach
2013-04-10 9:14 ` [PATCH v4 07/13] tegra: add driver for the clock and reset module Lucas Stach
` (6 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Lucas Stach @ 2013-04-10 9:14 UTC (permalink / raw)
To: barebox
We will follow the Linux kernel and go devicetree only for Tegra. This
doesn't prevent specific code for certain boards, but always requires a
valid DTB for all boards.
Also regenerate the AC100 defconfig to reflect this change.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
v4: unbrick ac100 defconfig
---
arch/arm/Kconfig | 3 +++
arch/arm/configs/toshiba_ac100_defconfig | 6 ++++--
arch/arm/dts/tegra20-paz00.dts | 12 ++++++++++++
arch/arm/dts/tegra20.dtsi | 5 +++++
4 files changed, 24 insertions(+), 2 deletions(-)
create mode 100644 arch/arm/dts/tegra20-paz00.dts
create mode 100644 arch/arm/dts/tegra20.dtsi
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index befed5d..fdd803e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -139,6 +139,9 @@ config ARCH_TEGRA
bool "NVIDIA Tegra"
select CPU_V7
select HAS_DEBUG_LL
+ select BUILTIN_DTB
+ select OFDEVICE
+ select OFTREE
config ARCH_ZYNQ
bool "Xilinx Zynq-based boards"
diff --git a/arch/arm/configs/toshiba_ac100_defconfig b/arch/arm/configs/toshiba_ac100_defconfig
index 065189d..6f7011b 100644
--- a/arch/arm/configs/toshiba_ac100_defconfig
+++ b/arch/arm/configs/toshiba_ac100_defconfig
@@ -1,3 +1,4 @@
+CONFIG_BUILTIN_DTB_NAME="tegra20-paz00"
CONFIG_ARCH_TEGRA=y
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
CONFIG_TEXT_BASE=0x01000000
@@ -14,6 +15,7 @@ CONFIG_ENABLE_DEVICE_NOISE=y
CONFIG_CMD_SLEEP=y
# CONFIG_CMD_TRUE is not set
# CONFIG_CMD_FALSE is not set
+CONFIG_CMD_TFTP=y
CONFIG_CMD_LOADB=y
CONFIG_CMD_LOADY=y
CONFIG_CMD_LOADS=y
@@ -23,11 +25,10 @@ CONFIG_CMD_SHA1SUM=y
CONFIG_CMD_BOOTM_SHOW_TYPE=y
CONFIG_CMD_RESET=y
CONFIG_CMD_GO=y
+CONFIG_CMD_OFTREE=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_PING=y
-CONFIG_CMD_TFTP=y
-CONFIG_FS_TFTP=y
CONFIG_NET_NETCONSOLE=y
CONFIG_DRIVER_SERIAL_NS16550=y
CONFIG_NET_USB=y
@@ -36,4 +37,5 @@ CONFIG_NET_USB_ASIX=y
CONFIG_USB=y
CONFIG_USB_EHCI=y
CONFIG_USB_STORAGE=y
+CONFIG_FS_TFTP=y
CONFIG_FS_FAT=y
diff --git a/arch/arm/dts/tegra20-paz00.dts b/arch/arm/dts/tegra20-paz00.dts
new file mode 100644
index 0000000..09ccb8b
--- /dev/null
+++ b/arch/arm/dts/tegra20-paz00.dts
@@ -0,0 +1,12 @@
+/dts-v1/;
+
+/include/ "tegra20.dtsi"
+
+/ {
+ model = "Toshiba AC100 / Dynabook AZ";
+ compatible = "compal,paz00", "nvidia,tegra20";
+
+ memory {
+ reg = <0x00000000 0x20000000>;
+ };
+};
diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
new file mode 100644
index 0000000..9f8860b
--- /dev/null
+++ b/arch/arm/dts/tegra20.dtsi
@@ -0,0 +1,5 @@
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "nvidia,tegra20";
+};
--
1.8.1.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v4 07/13] tegra: add driver for the clock and reset module
2013-04-10 9:14 [PATCH v4 01/13] tegra: pull in iomap.h from the Linux kernel Lucas Stach
` (4 preceding siblings ...)
2013-04-10 9:14 ` [PATCH v4 06/13] tegra: switch to DT only Lucas Stach
@ 2013-04-10 9:14 ` Lucas Stach
2013-04-10 9:14 ` [PATCH v4 08/13] tegra: add T20 timer driver Lucas Stach
` (5 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Lucas Stach @ 2013-04-10 9:14 UTC (permalink / raw)
To: barebox
Only a basic set of clocks is supported. This is a temporary solution
and will go away as soon as the port of the Tegra common clock code from
the Linux kernel is ready to go.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
arch/arm/Kconfig | 2 +
arch/arm/dts/tegra20.dtsi | 6 ++
arch/arm/mach-tegra/Makefile | 1 +
arch/arm/mach-tegra/include/mach/clkdev.h | 7 ++
arch/arm/mach-tegra/include/mach/tegra20-car.h | 22 +++++
arch/arm/mach-tegra/tegra20-car.c | 117 +++++++++++++++++++++++++
6 files changed, 155 insertions(+)
create mode 100644 arch/arm/mach-tegra/include/mach/clkdev.h
create mode 100644 arch/arm/mach-tegra/include/mach/tegra20-car.h
create mode 100644 arch/arm/mach-tegra/tegra20-car.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fdd803e..ed34d2c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -140,6 +140,8 @@ config ARCH_TEGRA
select CPU_V7
select HAS_DEBUG_LL
select BUILTIN_DTB
+ select COMMON_CLK
+ select CLKDEV_LOOKUP
select OFDEVICE
select OFTREE
diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
index 9f8860b..2edfda1 100644
--- a/arch/arm/dts/tegra20.dtsi
+++ b/arch/arm/dts/tegra20.dtsi
@@ -2,4 +2,10 @@
/ {
compatible = "nvidia,tegra20";
+
+ tegra_car: clock {
+ compatible = "nvidia,tegra20-car";
+ reg = <0x60006000 0x1000>;
+ #clock-cells = <1>;
+ };
};
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 11915e5..9aa7725 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -1,2 +1,3 @@
obj-y += clock.o
obj-y += reset.o
+obj-y += tegra20-car.o
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..04b37a8
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/tegra20-car.h b/arch/arm/mach-tegra/include/mach/tegra20-car.h
new file mode 100644
index 0000000..43ed059
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra20-car.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Register definitions */
+#define CRC_OSC_CTRL 0x050
+#define CRC_OSC_CTRL_OSC_FREQ_SHIFT 30
+#define CRC_OSC_CTRL_OSC_FREQ_MASK (0x3 << CRC_OSC_CTRL_OSC_FREQ_SHIFT)
+#define CRC_OSC_CTRL_PLL_REF_DIV_SHIFT 28
+#define CRC_OSC_CTRL_PLL_REF_DIV_MASK (0x3 << CRC_OSC_CTRL_PLL_REF_DIV_SHIFT)
diff --git a/arch/arm/mach-tegra/tegra20-car.c b/arch/arm/mach-tegra/tegra20-car.c
new file mode 100644
index 0000000..63c6ca5
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra20-car.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file
+ * @brief Device driver for the Tegra 20 clock and reset (CAR) controller
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <mach/iomap.h>
+
+#include <mach/tegra20-car.h>
+
+static void __iomem *car_base;
+
+enum tegra20_clks {
+ cpu, ac97 = 3, rtc, timer, uarta, gpio = 8, sdmmc2, i2s1 = 11, i2c1,
+ ndflash, sdmmc1, sdmmc4, twc, pwm, i2s2, epp, gr2d = 21, usbd, isp,
+ gr3d, ide, disp2, disp1, host1x, vcp, cache2 = 31, mem, ahbdma, apbdma,
+ kbc = 36, stat_mon, pmc, fuse, kfuse, sbc1, nor, spi, sbc2, xio, sbc3,
+ dvc, dsi, mipi = 50, hdmi, csi, tvdac, i2c2, uartc, emc = 57, usb2,
+ usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3,
+ pex, owr, afi, csite, pcie_xclk, avpucq = 75, la, irama = 84, iramb,
+ iramc, iramd, cram2, audio_2x, clk_d, csus = 92, cdev1, cdev2,
+ uartb = 96, vfir, spdif_in, spdif_out, vi, vi_sensor, tvo, cve,
+ osc, clk_32k, clk_m, sclk, cclk, hclk, pclk, blink, pll_a, pll_a_out0,
+ pll_c, pll_c_out1, pll_d, pll_d_out0, pll_e, pll_m, pll_m_out1,
+ pll_p, pll_p_out1, pll_p_out2, pll_p_out3, pll_p_out4, pll_u,
+ pll_x, audio, pll_ref, twd, clk_max,
+};
+
+static struct clk *clks[clk_max];
+
+static unsigned long get_osc_frequency(void)
+{
+ u32 osc_ctrl = readl(car_base + CRC_OSC_CTRL);
+
+ switch ((osc_ctrl & CRC_OSC_CTRL_OSC_FREQ_MASK) >>
+ CRC_OSC_CTRL_OSC_FREQ_SHIFT)
+ {
+ case 0:
+ return 13000000;
+ case 1:
+ return 19200000;
+ case 2:
+ return 12000000;
+ case 3:
+ return 26000000;
+ default:
+ return 0;
+ }
+}
+
+static unsigned int get_pll_ref_div(void)
+{
+ u32 osc_ctrl = readl(car_base + CRC_OSC_CTRL);
+
+ return 1U << ((osc_ctrl & CRC_OSC_CTRL_PLL_REF_DIV_MASK) >>
+ CRC_OSC_CTRL_PLL_REF_DIV_SHIFT);
+}
+
+static int tegra20_car_probe(struct device_d *dev)
+{
+ car_base = dev_request_mem_region(dev, 0);
+ if (!car_base)
+ return -EBUSY;
+
+ /* primary clocks */
+ clks[clk_m] = clk_fixed("clk_m", get_osc_frequency());
+ clks[clk_32k] = clk_fixed("clk_32k", 32768);
+
+ clks[pll_ref] = clk_fixed_factor("pll_ref", "clk_m", 1,
+ get_pll_ref_div());
+
+ /* derived clocks */
+ /* timer is a gate, but as it's enabled by BOOTROM we needn't worry */
+ clks[timer] = clk_fixed_factor("timer", "clk_m", 1, 1);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id tegra20_car_dt_ids[] = {
+ {
+ .compatible = "nvidia,tegra20-car",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d tegra20_car_driver = {
+ .probe = tegra20_car_probe,
+ .name = "tegra20-car",
+ .of_compatible = DRV_OF_COMPAT(tegra20_car_dt_ids),
+};
+
+static int tegra20_car_init(void)
+{
+ return platform_driver_register(&tegra20_car_driver);
+}
+postcore_initcall(tegra20_car_init);
--
1.8.1.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v4 08/13] tegra: add T20 timer driver
2013-04-10 9:14 [PATCH v4 01/13] tegra: pull in iomap.h from the Linux kernel Lucas Stach
` (5 preceding siblings ...)
2013-04-10 9:14 ` [PATCH v4 07/13] tegra: add driver for the clock and reset module Lucas Stach
@ 2013-04-10 9:14 ` Lucas Stach
2013-04-10 9:14 ` [PATCH v4 09/13] tegra: add T20 power management controller driver Lucas Stach
` (4 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Lucas Stach @ 2013-04-10 9:14 UTC (permalink / raw)
To: barebox
Replace the ad-hoc clocksource implementation with a proper driver for
the Tegra 20 timer. This driver is able to do the required hardware
initialisation itself.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
arch/arm/dts/tegra20.dtsi | 9 +++
arch/arm/mach-tegra/Makefile | 2 +-
arch/arm/mach-tegra/clock.c | 56 -----------------
arch/arm/mach-tegra/tegra20-car.c | 4 ++
arch/arm/mach-tegra/tegra20-timer.c | 119 ++++++++++++++++++++++++++++++++++++
5 files changed, 133 insertions(+), 57 deletions(-)
delete mode 100644 arch/arm/mach-tegra/clock.c
create mode 100644 arch/arm/mach-tegra/tegra20-timer.c
diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
index 2edfda1..cc76527 100644
--- a/arch/arm/dts/tegra20.dtsi
+++ b/arch/arm/dts/tegra20.dtsi
@@ -3,6 +3,15 @@
/ {
compatible = "nvidia,tegra20";
+ timer@60005000 {
+ compatible = "nvidia,tegra20-timer";
+ reg = <0x60005000 0x60>;
+ interrupts = <0 0 0x04
+ 0 1 0x04
+ 0 41 0x04
+ 0 42 0x04>;
+ };
+
tegra_car: clock {
compatible = "nvidia,tegra20-car";
reg = <0x60006000 0x1000>;
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 9aa7725..1112d11 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -1,3 +1,3 @@
-obj-y += clock.o
obj-y += reset.o
obj-y += tegra20-car.o
+obj-y += tegra20-timer.o
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
deleted file mode 100644
index 82065ee..0000000
--- a/arch/arm/mach-tegra/clock.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2011 Antony Pavlov <antonynpavlov@gmail.com>
- *
- * This file is part of barebox.
- * See file CREDITS for list of people who contributed to this project.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-/**
- * @file
- * @brief Clocksource based on Tegra internal timer
- */
-
-#include <common.h>
-#include <clock.h>
-#include <linux/list.h>
-#include <linux/clk.h>
-#include <init.h>
-#include <asm/io.h>
-#include <mach/iomap.h>
-
-static void __iomem *timer_reg_base = (void __iomem *) (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 uint64_t tegra_clocksource_read(void)
-{
- return timer_readl(0x10);
-}
-
-static struct clocksource cs = {
- .read = tegra_clocksource_read,
- .mask = 0xffffffff,
-};
-
-/* FIXME: here we have no initialization. All initialization made by U-Boot */
-static int clocksource_init(void)
-{
- cs.mult = clocksource_hz2mult(1000000, cs.shift);
- init_clock(&cs);
-
- return 0;
-}
-core_initcall(clocksource_init);
diff --git a/arch/arm/mach-tegra/tegra20-car.c b/arch/arm/mach-tegra/tegra20-car.c
index 63c6ca5..08033d7 100644
--- a/arch/arm/mach-tegra/tegra20-car.c
+++ b/arch/arm/mach-tegra/tegra20-car.c
@@ -23,6 +23,7 @@
#include <init.h>
#include <io.h>
#include <linux/clk.h>
+#include <linux/clkdev.h>
#include <linux/err.h>
#include <mach/iomap.h>
@@ -93,6 +94,9 @@ static int tegra20_car_probe(struct device_d *dev)
/* timer is a gate, but as it's enabled by BOOTROM we needn't worry */
clks[timer] = clk_fixed_factor("timer", "clk_m", 1, 1);
+ /* device to clock links */
+ clkdev_add_physbase(clks[timer], TEGRA_TMR1_BASE, NULL);
+
return 0;
}
diff --git a/arch/arm/mach-tegra/tegra20-timer.c b/arch/arm/mach-tegra/tegra20-timer.c
new file mode 100644
index 0000000..aafbfd4
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra20-timer.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file
+ * @brief Device driver for the Tegra 20 timer, which exposes a clocksource.
+ */
+
+#include <common.h>
+#include <clock.h>
+#include <init.h>
+#include <io.h>
+#include <linux/clk.h>
+
+/* register definitions */
+#define TIMERUS_CNTR_1US 0x10
+#define TIMERUS_USEC_CFG 0x14
+
+static void __iomem *timer_base;
+
+static uint64_t tegra20_timer_cs_read(void)
+{
+ return readl(timer_base + TIMERUS_CNTR_1US);
+}
+
+static struct clocksource cs = {
+ .read = tegra20_timer_cs_read,
+ .mask = CLOCKSOURCE_MASK(32),
+};
+
+static int tegra20_timer_probe(struct device_d *dev)
+{
+ struct clk *timer_clk;
+ unsigned long rate;
+ u32 reg;
+
+ /* use only one timer */
+ if (timer_base)
+ return -EBUSY;
+
+ timer_base = dev_request_mem_region(dev, 0);
+ if (!timer_base) {
+ dev_err(dev, "could not get memory region\n");
+ return -ENODEV;
+ }
+
+ timer_clk = clk_get(dev, NULL);
+ if (!timer_clk) {
+ dev_err(dev, "could not get clock\n");
+ return -ENODEV;
+ }
+
+ clk_enable(timer_clk);
+
+ /*
+ * calibrate timer to run at 1MHz
+ * TIMERUS_USEC_CFG selects the scale down factor with bits [0:7]
+ * representing the divisor and bits [8:15] representing the dividend
+ * each in n+1 form.
+ */
+ rate = clk_get_rate(timer_clk);
+ switch (rate) {
+ case 12000000:
+ reg = 0x000b;
+ break;
+ case 13000000:
+ reg = 0x000c;
+ break;
+ case 19200000:
+ reg = 0x045f;
+ break;
+ case 26000000:
+ reg = 0x0019;
+ break;
+ default:
+ reg = 0;
+ dev_warn(dev, "unknown timer clock rate\n");
+ break;
+ }
+ writel(reg, timer_base + TIMERUS_USEC_CFG);
+
+ cs.mult = clocksource_hz2mult(1000000, cs.shift);
+ init_clock(&cs);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id tegra20_timer_dt_ids[] = {
+ {
+ .compatible = "nvidia,tegra20-timer",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d tegra20_timer_driver = {
+ .probe = tegra20_timer_probe,
+ .name = "tegra20-timer",
+ .of_compatible = DRV_OF_COMPAT(tegra20_timer_dt_ids),
+};
+
+static int tegra20_timer_init(void)
+{
+ return platform_driver_register(&tegra20_timer_driver);
+}
+coredevice_initcall(tegra20_timer_init);
--
1.8.1.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v4 09/13] tegra: add T20 power management controller driver
2013-04-10 9:14 [PATCH v4 01/13] tegra: pull in iomap.h from the Linux kernel Lucas Stach
` (6 preceding siblings ...)
2013-04-10 9:14 ` [PATCH v4 08/13] tegra: add T20 timer driver Lucas Stach
@ 2013-04-10 9:14 ` Lucas Stach
2013-04-10 9:14 ` [PATCH v4 10/13] tegra: add common lowlevel startup Lucas Stach
` (3 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Lucas Stach @ 2013-04-10 9:14 UTC (permalink / raw)
To: barebox
Currently only implements system wide reset functionality.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
arch/arm/dts/tegra20.dtsi | 5 ++
arch/arm/mach-tegra/Makefile | 2 +-
arch/arm/mach-tegra/include/mach/tegra20-pmc.h | 37 ++++++++++++++
arch/arm/mach-tegra/reset.c | 39 ---------------
arch/arm/mach-tegra/tegra20-pmc.c | 68 ++++++++++++++++++++++++++
5 files changed, 111 insertions(+), 40 deletions(-)
create mode 100644 arch/arm/mach-tegra/include/mach/tegra20-pmc.h
delete mode 100644 arch/arm/mach-tegra/reset.c
create mode 100644 arch/arm/mach-tegra/tegra20-pmc.c
diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
index cc76527..91858ec 100644
--- a/arch/arm/dts/tegra20.dtsi
+++ b/arch/arm/dts/tegra20.dtsi
@@ -17,4 +17,9 @@
reg = <0x60006000 0x1000>;
#clock-cells = <1>;
};
+
+ pmc {
+ compatible = "nvidia,tegra20-pmc";
+ reg = <0x7000e400 0x400>;
+ };
};
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 1112d11..131a1d9 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -1,3 +1,3 @@
-obj-y += reset.o
obj-y += tegra20-car.o
+obj-y += tegra20-pmc.o
obj-y += tegra20-timer.o
diff --git a/arch/arm/mach-tegra/include/mach/tegra20-pmc.h b/arch/arm/mach-tegra/include/mach/tegra20-pmc.h
new file mode 100644
index 0000000..a905399
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra20-pmc.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* register definitions */
+#define PMC_CNTRL 0x000
+#define PMC_CNTRL_FUSE_OVERRIDE (1 << 18)
+#define PMC_CNTRL_INTR_POLARITY (1 << 17)
+#define PMC_CNTRL_CPUPWRREQ_OE (1 << 16)
+#define PMC_CNTRL_CPUPWRREQ_POLARITY (1 << 15)
+#define PMC_CNTRL_SIDE_EFFECT_LP0 (1 << 14)
+#define PMC_CNTRL_AOINIT (1 << 13)
+#define PMC_CNTRL_PWRGATE_DIS (1 << 12)
+#define PMC_CNTRL_SYSCLK_OE (1 << 11)
+#define PMC_CNTRL_SYSCLK_POLARITY (1 << 10)
+#define PMC_CNTRL_PWRREQ_OE (1 << 9)
+#define PMC_CNTRL_PWRREQ_POLARITY (1 << 8)
+#define PMC_CNTRL_BLINK_EN (1 << 7)
+#define PMC_CNTRL_GLITCHDET_DIS (1 << 6)
+#define PMC_CNTRL_LATCHWAKE_EN (1 << 5)
+#define PMC_CNTRL_MAIN_RST (1 << 4)
+#define PMC_CNTRL_KBC_RST (1 << 3)
+#define PMC_CNTRL_RTC_RST (1 << 2)
+#define PMC_CNTRL_RTC_CLK_DIS (1 << 1)
+#define PMC_CNTRL_KBC_CLK_DIS (1 << 0)
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
deleted file mode 100644
index 91f9b3b..0000000
--- a/arch/arm/mach-tegra/reset.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2011 Antony Pavlov <antonynpavlov@gmail.com>
- *
- * This file is part of barebox.
- * See file CREDITS for list of people who contributed to this project.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-/**
- * @file
- * @brief Resetting an malta board
- */
-
-#include <common.h>
-#include <asm/io.h>
-#include <mach/iomap.h>
-
-#define PRM_RSTCTRL TEGRA_PMC_BASE
-
-void __noreturn reset_cpu(ulong addr)
-{
- int rstctrl;
-
- rstctrl = __raw_readl((char *)PRM_RSTCTRL);
- rstctrl |= 0x10;
- __raw_writel(rstctrl, (char *)PRM_RSTCTRL);
-
- unreachable();
-}
-EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-tegra/tegra20-pmc.c b/arch/arm/mach-tegra/tegra20-pmc.c
new file mode 100644
index 0000000..b7d84d8
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra20-pmc.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file
+ * @brief Device driver for the Tegra 20 power management controller.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+
+#include <mach/tegra20-pmc.h>
+
+static void __iomem *pmc_base;
+
+/* main SoC reset trigger */
+void __noreturn reset_cpu(ulong addr)
+{
+ writel(PMC_CNTRL_MAIN_RST, pmc_base + PMC_CNTRL);
+
+ unreachable();
+}
+EXPORT_SYMBOL(reset_cpu);
+
+static int tegra20_pmc_probe(struct device_d *dev)
+{
+ pmc_base = dev_request_mem_region(dev, 0);
+ if (!pmc_base) {
+ dev_err(dev, "could not get memory region\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id tegra20_pmc_dt_ids[] = {
+ {
+ .compatible = "nvidia,tegra20-pmc",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d tegra20_pmc_driver = {
+ .probe = tegra20_pmc_probe,
+ .name = "tegra20-pmc",
+ .of_compatible = DRV_OF_COMPAT(tegra20_pmc_dt_ids),
+};
+
+static int tegra20_pmc_init(void)
+{
+ return platform_driver_register(&tegra20_pmc_driver);
+}
+coredevice_initcall(tegra20_pmc_init);
--
1.8.1.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v4 10/13] tegra: add common lowlevel startup
2013-04-10 9:14 [PATCH v4 01/13] tegra: pull in iomap.h from the Linux kernel Lucas Stach
` (7 preceding siblings ...)
2013-04-10 9:14 ` [PATCH v4 09/13] tegra: add T20 power management controller driver Lucas Stach
@ 2013-04-10 9:14 ` Lucas Stach
2013-04-10 9:14 ` [PATCH v4 11/13] tegra: add generic debug UART support Lucas Stach
` (2 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Lucas Stach @ 2013-04-10 9:14 UTC (permalink / raw)
To: barebox
All Tegra20 boards have a common startup sequence. Also there is an
agreement on how to find out about the installed amount of RAM and other
information needed by early startup. So as there is really no need to do
any lowlevel stuff per board, we can just do it at the ARCH level.
This also enables the first stage loading of barebox by detecting the
currently running CPU and booting the main CPU cluster if neccesary.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
arch/arm/boards/toshiba-ac100/Makefile | 1 -
arch/arm/boards/toshiba-ac100/lowlevel.c | 10 --
arch/arm/mach-tegra/Makefile | 3 +
arch/arm/mach-tegra/include/mach/iomap.h | 3 +
arch/arm/mach-tegra/include/mach/lowlevel.h | 113 ++++++++++++
arch/arm/mach-tegra/include/mach/tegra20-car.h | 157 +++++++++++++++++
arch/arm/mach-tegra/include/mach/tegra20-pmc.h | 30 ++++
arch/arm/mach-tegra/tegra_avp_init.c | 228 +++++++++++++++++++++++++
arch/arm/mach-tegra/tegra_maincomplex_init.c | 46 +++++
9 files changed, 580 insertions(+), 11 deletions(-)
delete mode 100644 arch/arm/boards/toshiba-ac100/lowlevel.c
create mode 100644 arch/arm/mach-tegra/include/mach/lowlevel.h
create mode 100644 arch/arm/mach-tegra/tegra_avp_init.c
create mode 100644 arch/arm/mach-tegra/tegra_maincomplex_init.c
diff --git a/arch/arm/boards/toshiba-ac100/Makefile b/arch/arm/boards/toshiba-ac100/Makefile
index 4d321e1..9e14763 100644
--- a/arch/arm/boards/toshiba-ac100/Makefile
+++ b/arch/arm/boards/toshiba-ac100/Makefile
@@ -1,3 +1,2 @@
obj-y += board.o
obj-$(CONFIG_DRIVER_SERIAL_NS16550) += serial.o
-lwl-y += lowlevel.o
diff --git a/arch/arm/boards/toshiba-ac100/lowlevel.c b/arch/arm/boards/toshiba-ac100/lowlevel.c
deleted file mode 100644
index 2f99d70..0000000
--- a/arch/arm/boards/toshiba-ac100/lowlevel.c
+++ /dev/null
@@ -1,10 +0,0 @@
-#include <common.h>
-#include <sizes.h>
-#include <asm/barebox-arm-head.h>
-#include <asm/barebox-arm.h>
-
-void __naked barebox_arm_reset_vector(void)
-{
- arm_cpu_lowlevel_init();
- barebox_arm_entry(0x0, SZ_512M, 0);
-}
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 131a1d9..0807af6 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -1,3 +1,6 @@
+CFLAGS_tegra_avp_init.o := -mcpu=arm7tdmi -march=armv4t
+lwl-y += tegra_avp_init.o
+lwl-y += tegra_maincomplex_init.o
obj-y += tegra20-car.o
obj-y += tegra20-pmc.o
obj-y += tegra20-timer.o
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
index 6ca6504..70eebb4 100644
--- a/arch/arm/mach-tegra/include/mach/iomap.h
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -59,6 +59,9 @@
#define TEGRA_GART_BASE 0x58000000
#define TEGRA_GART_SIZE SZ_32M
+#define TEGRA_UP_TAG_BASE 0x60000000
+#define TEGRA_UP_TAG_SIZE SZ_4K
+
#define TEGRA_RES_SEMA_BASE 0x60001000
#define TEGRA_RES_SEMA_SIZE SZ_4K
diff --git a/arch/arm/mach-tegra/include/mach/lowlevel.h b/arch/arm/mach-tegra/include/mach/lowlevel.h
new file mode 100644
index 0000000..bd1a8db
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/lowlevel.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file
+ * @brief Boot informations provided by the Tegra SoC and it's BootROM. All
+ * accessor functions are a header only implementations, as they are meant to
+ * be used by both the main CPU complex (ARMv7) and the AVP (ARMv4).
+ */
+
+#include <sizes.h>
+#include <io.h>
+#include <mach/iomap.h>
+
+/* Bootinfotable */
+
+#define NV_BIT_BCTSIZE 0x38 /* size of the BCT in IRAM */
+#define NV_BIT_BCTPTR 0x3C /* location of the BCT in IRAM */
+
+/* ODM data */
+#define BCT_ODMDATA_OFFSET 12 /* offset from the _end_ of the BCT */
+
+#define T20_ODMDATA_RAMSIZE_SHIFT 28
+#define T20_ODMDATA_RAMSIZE_MASK (3 << T20_ODMDATA_RAMSIZE_SHIFT)
+
+static inline u32 tegra_get_odmdata(void)
+{
+ u32 bctsize, bctptr, odmdata;
+
+ bctsize = cpu_readl(TEGRA_IRAM_BASE + NV_BIT_BCTSIZE);
+ bctptr = cpu_readl(TEGRA_IRAM_BASE + NV_BIT_BCTPTR);
+
+ odmdata = cpu_readl(bctptr + bctsize - BCT_ODMDATA_OFFSET);
+
+ return odmdata;
+}
+
+/* chip ID */
+#define APB_MISC_HIDREV 0x804
+#define HIDREV_CHIPID_SHIFT 8
+#define HIDREV_CHIPID_MASK (0xff << HIDREV_CHIPID_SHIFT)
+
+enum tegra_chiptype {
+ TEGRA_UNK_REV = -1,
+ TEGRA20 = 0,
+};
+
+static inline enum tegra_chiptype tegra_get_chiptype(void)
+{
+ u32 hidrev;
+
+ hidrev = readl(TEGRA_APB_MISC_BASE + APB_MISC_HIDREV);
+
+ switch ((hidrev & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT) {
+ case 0x20:
+ return TEGRA20;
+ default:
+ return TEGRA_UNK_REV;
+ }
+}
+
+static inline int tegra_get_num_cores(void)
+{
+ switch (tegra_get_chiptype()) {
+ case TEGRA20:
+ return 2;
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+/* Runtime data */
+static inline int tegra_cpu_is_maincomplex(void)
+{
+ u32 tag0;
+
+ tag0 = readl(TEGRA_UP_TAG_BASE);
+
+ return (tag0 & 0xff) == 0x55;
+}
+
+static inline uint32_t tegra20_get_ramsize(void)
+{
+ switch ((tegra_get_odmdata() & T20_ODMDATA_RAMSIZE_MASK) >>
+ T20_ODMDATA_RAMSIZE_SHIFT)
+ {
+ case 1:
+ return SZ_256M;
+ default:
+ case 2:
+ return SZ_512M;
+ case 3:
+ return SZ_1G;
+ }
+}
+
+/* reset vector for the main CPU complex */
+void tegra_maincomplex_entry(void);
diff --git a/arch/arm/mach-tegra/include/mach/tegra20-car.h b/arch/arm/mach-tegra/include/mach/tegra20-car.h
index 43ed059..5669732 100644
--- a/arch/arm/mach-tegra/include/mach/tegra20-car.h
+++ b/arch/arm/mach-tegra/include/mach/tegra20-car.h
@@ -15,8 +15,165 @@
*/
/* Register definitions */
+#define CRC_CLK_OUT_ENB_L 0x010
+#define CRC_CLK_OUT_ENB_L_CACHE2 (1 << 31)
+#define CRC_CLK_OUT_ENB_L_VCP (1 << 29)
+#define CRC_CLK_OUT_ENB_L_HOST1X (1 << 28)
+#define CRC_CLK_OUT_ENB_L_DISP1 (1 << 27)
+#define CRC_CLK_OUT_ENB_L_DISP2 (1 << 26)
+#define CRC_CLK_OUT_ENB_L_IDE (1 << 25)
+#define CRC_CLK_OUT_ENB_L_3D (1 << 24)
+#define CRC_CLK_OUT_ENB_L_ISP (1 << 23)
+#define CRC_CLK_OUT_ENB_L_USBD (1 << 22)
+#define CRC_CLK_OUT_ENB_L_2D (1 << 21)
+#define CRC_CLK_OUT_ENB_L_VI (1 << 20)
+#define CRC_CLK_OUT_ENB_L_EPP (1 << 19)
+#define CRC_CLK_OUT_ENB_L_I2S2 (1 << 18)
+#define CRC_CLK_OUT_ENB_L_PWM (1 << 17)
+#define CRC_CLK_OUT_ENB_L_TWC (1 << 16)
+#define CRC_CLK_OUT_ENB_L_SDMMC4 (1 << 15)
+#define CRC_CLK_OUT_ENB_L_SDMMC1 (1 << 14)
+#define CRC_CLK_OUT_ENB_L_NDFLASH (1 << 13)
+#define CRC_CLK_OUT_ENB_L_I2C1 (1 << 12)
+#define CRC_CLK_OUT_ENB_L_I2S1 (1 << 11)
+#define CRC_CLK_OUT_ENB_L_SPDIF (1 << 10)
+#define CRC_CLK_OUT_ENB_L_SDMMC2 (1 << 9)
+#define CRC_CLK_OUT_ENB_L_GPIO (1 << 8)
+#define CRC_CLK_OUT_ENB_L_UART2 (1 << 7)
+#define CRC_CLK_OUT_ENB_L_UART1 (1 << 6)
+#define CRC_CLK_OUT_ENB_L_TMR (1 << 5)
+#define CRC_CLK_OUT_ENB_L_RTC (1 << 4)
+#define CRC_CLK_OUT_ENB_L_AC97 (1 << 3)
+#define CRC_CLK_OUT_ENB_L_CPU (1 << 0)
+
+#define CRC_SCLK_BURST_POLICY 0x028
+#define CRC_SCLK_BURST_POLICY_SYS_STATE_SHIFT 28
+#define CRC_SCLK_BURST_POLICY_SYS_STATE_FIQ 8
+#define CRC_SCLK_BURST_POLICY_SYS_STATE_IRQ 4
+#define CRC_SCLK_BURST_POLICY_SYS_STATE_RUN 2
+#define CRC_SCLK_BURST_POLICY_SYS_STATE_IDLE 1
+#define CRC_SCLK_BURST_POLICY_SYS_STATE_STDBY 0
+
+#define CRC_SUPER_SCLK_DIV 0x02c
+#define CRC_SUPER_SDIV_ENB (1 << 31)
+#define CRC_SUPER_SDIV_DIS_FROM_COP_FIQ (1 << 27)
+#define CRC_SUPER_SDIV_DIS_FROM_CPU_FIQ (1 << 26)
+#define CRC_SUPER_SDIV_DIS_FROM_COP_IRQ (1 << 25)
+#define CRC_SUPER_SDIV_DIS_FROM_CPU_IRQ (1 << 24)
+#define CRC_SUPER_SDIV_DIVIDEND_SHIFT 8
+#define CRC_SUPER_SDIV_DIVIDEND_MASK (0xff << CRC_SUPER_SDIV_DIVIDEND_SHIFT)
+#define CRC_SUPER_SDIV_DIVISOR_SHIFT 0
+#define CRC_SUPER_SDIV_DIVISOR_MASK (0xff << CRC_SUPER_SDIV_DIVISOR_SHIFT)
+
+#define CRC_CLK_CPU_CMPLX 0x04c
+#define CRC_CLK_CPU_CMPLX_CPU3_CLK_STP (1 << 11)
+#define CRC_CLK_CPU_CMPLX_CPU2_CLK_STP (1 << 10)
+#define CRC_CLK_CPU_CMPLX_CPU1_CLK_STP (1 << 9)
+#define CRC_CLK_CPU_CMPLX_CPU0_CLK_STP (1 << 8)
+#define CRC_CLK_CPU_CMPLX_CPU_BRIDGE_DIV_SHIFT 0
+#define CRC_CLK_CPU_CMPLX_CPU_BRIDGE_DIV_4 3
+#define CRC_CLK_CPU_CMPLX_CPU_BRIDGE_DIV_3 2
+#define CRC_CLK_CPU_CMPLX_CPU_BRIDGE_DIV_2 1
+#define CRC_CLK_CPU_CMPLX_CPU_BRIDGE_DIV_1 0
+
#define CRC_OSC_CTRL 0x050
#define CRC_OSC_CTRL_OSC_FREQ_SHIFT 30
#define CRC_OSC_CTRL_OSC_FREQ_MASK (0x3 << CRC_OSC_CTRL_OSC_FREQ_SHIFT)
#define CRC_OSC_CTRL_PLL_REF_DIV_SHIFT 28
#define CRC_OSC_CTRL_PLL_REF_DIV_MASK (0x3 << CRC_OSC_CTRL_PLL_REF_DIV_SHIFT)
+
+#define CRC_PLLX_BASE 0x0e0
+#define CRC_PLLX_BASE_BYPASS (1 << 31)
+#define CRC_PLLX_BASE_ENABLE (1 << 30)
+#define CRC_PLLX_BASE_REF_DIS (1 << 29)
+#define CRC_PLLX_BASE_LOCK (1 << 27)
+#define CRC_PLLX_BASE_DIVP_SHIFT 20
+#define CRC_PLLX_BASE_DIVP_MASK (0x7 << CRC_PLLX_BASE_DIVP_SHIFT)
+#define CRC_PLLX_BASE_DIVN_SHIFT 8
+#define CRC_PLLX_BASE_DIVN_MASK (0x3ff << CRC_PLLX_BASE_DIVN_SHIFT)
+#define CRC_PLLX_BASE_DIVM_SHIFT 0
+#define CRC_PLLX_BASE_DIVM_MASK (0xf << CRC_PLLX_BASE_DIVM_SHIFT)
+
+#define CRC_PLLX_MISC 0x0e4
+#define CRC_PLLX_MISC_SETUP_SHIFT 24
+#define CRC_PLLX_MISC_SETUP_MASK (0xf << CRC_PLLX_MISC_SETUP_SHIFT)
+#define CRC_PLLX_MISC_PTS_SHIFT 22
+#define CRC_PLLX_MISC_PTS_MASK (0x3 << CRC_PLLX_MISC_PTS_SHIFT)
+#define CRC_PLLX_MISC_DCCON (1 << 20)
+#define CRC_PLLX_MISC_LOCK_ENABLE (1 << 18)
+#define CRC_PLLX_MISC_LOCK_SEL_SHIFT 12
+#define CRC_PLLX_MISC_LOCK_SEL_MASK (0x3f << CRC_PLLX_MISC_LOCK_SEL_SHIFT)
+#define CRC_PLLX_MISC_CPCON_SHIFT 8
+#define CRC_PLLX_MISC_CPCON_MASK (0xf << CRC_PLLX_MISC_CPCON_SHIFT)
+#define CRC_PLLX_MISC_LFCON_SHIFT 4
+#define CRC_PLLX_MISC_LFCON_MASK (0xf << CRC_PLLX_MISC_LFCON_SHIFT)
+#define CRC_PLLX_MISC_VCOCON_SHIFT 0
+#define CRC_PLLX_MISC_VCOCON_MASK (0xf << CRC_PLLX_MISC_VCOCON_SHIFT)
+
+#define CRC_RST_DEV_L_SET 0x300
+#define CRC_RST_DEV_L_SET_CACHE2 (1 << 31)
+#define CRC_RST_DEV_L_SET_VCP (1 << 29)
+#define CRC_RST_DEV_L_SET_HOST1X (1 << 28)
+#define CRC_RST_DEV_L_SET_DISP1 (1 << 27)
+#define CRC_RST_DEV_L_SET_DISP2 (1 << 26)
+#define CRC_RST_DEV_L_SET_IDE (1 << 25)
+#define CRC_RST_DEV_L_SET_3D (1 << 24)
+#define CRC_RST_DEV_L_SET_ISP (1 << 23)
+#define CRC_RST_DEV_L_SET_USBD (1 << 22)
+#define CRC_RST_DEV_L_SET_2D (1 << 21)
+#define CRC_RST_DEV_L_SET_VI (1 << 20)
+#define CRC_RST_DEV_L_SET_EPP (1 << 19)
+#define CRC_RST_DEV_L_SET_I2S2 (1 << 18)
+#define CRC_RST_DEV_L_SET_PWM (1 << 17)
+#define CRC_RST_DEV_L_SET_TWC (1 << 16)
+#define CRC_RST_DEV_L_SET_SDMMC4 (1 << 15)
+#define CRC_RST_DEV_L_SET_SDMMC1 (1 << 14)
+#define CRC_RST_DEV_L_SET_NDFLASH (1 << 13)
+#define CRC_RST_DEV_L_SET_I2C1 (1 << 12)
+#define CRC_RST_DEV_L_SET_I2S1 (1 << 11)
+#define CRC_RST_DEV_L_SET_SPDIF (1 << 10)
+#define CRC_RST_DEV_L_SET_SDMMC2 (1 << 9)
+#define CRC_RST_DEV_L_SET_GPIO (1 << 8)
+#define CRC_RST_DEV_L_SET_UART2 (1 << 7)
+#define CRC_RST_DEV_L_SET_UART1 (1 << 6)
+#define CRC_RST_DEV_L_SET_TMR (1 << 5)
+#define CRC_RST_DEV_L_SET_AC97 (1 << 3)
+#define CRC_RST_DEV_L_SET_SYS (1 << 2)
+#define CRC_RST_DEV_L_SET_COP (1 << 1)
+#define CRC_RST_DEV_L_SET_CPU (1 << 0)
+
+#define CRC_RST_DEV_L_CLR 0x304
+#define CRC_RST_DEV_L_CLR_CACHE2 (1 << 31)
+#define CRC_RST_DEV_L_CLR_VCP (1 << 29)
+#define CRC_RST_DEV_L_CLR_HOST1X (1 << 28)
+#define CRC_RST_DEV_L_CLR_DISP1 (1 << 27)
+#define CRC_RST_DEV_L_CLR_DISP2 (1 << 26)
+#define CRC_RST_DEV_L_CLR_IDE (1 << 25)
+#define CRC_RST_DEV_L_CLR_3D (1 << 24)
+#define CRC_RST_DEV_L_CLR_ISP (1 << 23)
+#define CRC_RST_DEV_L_CLR_USBD (1 << 22)
+#define CRC_RST_DEV_L_CLR_2D (1 << 21)
+#define CRC_RST_DEV_L_CLR_VI (1 << 20)
+#define CRC_RST_DEV_L_CLR_EPP (1 << 19)
+#define CRC_RST_DEV_L_CLR_I2S2 (1 << 18)
+#define CRC_RST_DEV_L_CLR_PWM (1 << 17)
+#define CRC_RST_DEV_L_CLR_TWC (1 << 16)
+#define CRC_RST_DEV_L_CLR_SDMMC4 (1 << 15)
+#define CRC_RST_DEV_L_CLR_SDMMC1 (1 << 14)
+#define CRC_RST_DEV_L_CLR_NDFLASH (1 << 13)
+#define CRC_RST_DEV_L_CLR_I2C1 (1 << 12)
+#define CRC_RST_DEV_L_CLR_I2S1 (1 << 11)
+#define CRC_RST_DEV_L_CLR_SPDIF (1 << 10)
+#define CRC_RST_DEV_L_CLR_SDMMC2 (1 << 9)
+#define CRC_RST_DEV_L_CLR_GPIO (1 << 8)
+#define CRC_RST_DEV_L_CLR_UART2 (1 << 7)
+#define CRC_RST_DEV_L_CLR_UART1 (1 << 6)
+#define CRC_RST_DEV_L_CLR_TMR (1 << 5)
+#define CRC_RST_DEV_L_CLR_AC97 (1 << 3)
+#define CRC_RST_DEV_L_CLR_SYS (1 << 2)
+#define CRC_RST_DEV_L_CLR_COP (1 << 1)
+#define CRC_RST_DEV_L_CLR_CPU (1 << 0)
+
+#define CRC_RST_CPU_CMPLX_SET 0x340
+
+#define CRC_RST_CPU_CMPLX_CLR 0x344
diff --git a/arch/arm/mach-tegra/include/mach/tegra20-pmc.h b/arch/arm/mach-tegra/include/mach/tegra20-pmc.h
index a905399..d56b845 100644
--- a/arch/arm/mach-tegra/include/mach/tegra20-pmc.h
+++ b/arch/arm/mach-tegra/include/mach/tegra20-pmc.h
@@ -35,3 +35,33 @@
#define PMC_CNTRL_RTC_RST (1 << 2)
#define PMC_CNTRL_RTC_CLK_DIS (1 << 1)
#define PMC_CNTRL_KBC_CLK_DIS (1 << 0)
+
+#define PMC_PWRGATE_TOGGLE 0x030
+#define PMC_PWRGATE_TOGGLE_PARTID_SHIFT 0
+#define PMC_PWRGATE_TOGGLE_PARTID_MASK (0x3 << PMC_PWRGATE_TOGGLE_PARTID_SHIFT)
+#define PMC_PWRGATE_TOGGLE_PARTID_CPU 0
+#define PMC_PWRGATE_TOGGLE_PARTID_TD 1
+#define PMC_PWRGATE_TOGGLE_PARTID_VE 2
+#define PMC_PWRGATE_TOGGLE_PARTID_PCX 3
+#define PMC_PWRGATE_TOGGLE_PARTID_VDE 4
+#define PMC_PWRGATE_TOGGLE_PARTID_L2C 5
+#define PMC_PWRGATE_TOGGLE_PARTID_MPE 6
+#define PMC_PWRGATE_TOGGLE_START (1 << 8)
+
+#define PMC_REMOVE_CLAMPING_CMD 0x034
+#define PMC_REMOVE_CLAMPING_CMD_MPE (1 << 6)
+#define PMC_REMOVE_CLAMPING_CMD_L2C (1 << 5)
+#define PMC_REMOVE_CLAMPING_CMD_PCX (1 << 4)
+#define PMC_REMOVE_CLAMPING_CMD_VDE (1 << 3)
+#define PMC_REMOVE_CLAMPING_CMD_VE (1 << 2)
+#define PMC_REMOVE_CLAMPING_CMD_TD (1 << 1)
+#define PMC_REMOVE_CLAMPING_CMD_CPU (1 << 0)
+
+#define PMC_PWRGATE_STATUS 0x038
+#define PMC_PWRGATE_STATUS_MPE (1 << 6)
+#define PMC_PWRGATE_STATUS_L2C (1 << 5)
+#define PMC_PWRGATE_STATUS_VDE (1 << 4)
+#define PMC_PWRGATE_STATUS_PCX (1 << 3)
+#define PMC_PWRGATE_STATUS_VE (1 << 2)
+#define PMC_PWRGATE_STATUS_TD (1 << 1)
+#define PMC_PWRGATE_STATUS_CPU (1 << 0)
diff --git a/arch/arm/mach-tegra/tegra_avp_init.c b/arch/arm/mach-tegra/tegra_avp_init.c
new file mode 100644
index 0000000..76164b5
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra_avp_init.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * Partly based on code (C) Copyright 2010-2011
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <common.h>
+#include <asm/barebox-arm-head.h>
+#include <mach/lowlevel.h>
+#include <mach/tegra20-car.h>
+#include <mach/tegra20-pmc.h>
+
+static inline void tegra_cpu_lowlevel_setup(void)
+{
+ uint32_t r;
+
+ /* set the cpu to SVC32 mode */
+ __asm__ __volatile__("mrs %0, cpsr":"=r"(r));
+ r &= ~0x1f;
+ r |= 0xd3;
+ __asm__ __volatile__("msr cpsr, %0" : : "r"(r));
+}
+
+/* instruct the PMIC to enable the CPU power rail */
+static void enable_maincomplex_powerrail(void)
+{
+ u32 reg;
+
+ reg = readl(TEGRA_PMC_BASE + PMC_CNTRL);
+ reg |= PMC_CNTRL_CPUPWRREQ_OE;
+ writel(reg, TEGRA_PMC_BASE);
+}
+
+/* put every core in the main CPU complex into reset state */
+static void assert_maincomplex_reset(int num_cores)
+{
+ u32 mask = 0;
+ int i;
+
+ for (i = 0; i < num_cores; i++) {
+ mask |= 0x1111 << i;
+ }
+
+ writel(mask, TEGRA_CLK_RESET_BASE + CRC_RST_CPU_CMPLX_SET);
+ writel(CRC_RST_DEV_L_SET_CPU, TEGRA_CLK_RESET_BASE + CRC_RST_DEV_L_SET);
+}
+
+/* release reset state of the first core of the main CPU complex */
+static void deassert_cpu0_reset(void)
+{
+ writel(0x1111, TEGRA_CLK_RESET_BASE + CRC_RST_CPU_CMPLX_CLR);
+ writel(CRC_RST_DEV_L_CLR_CPU, TEGRA_CLK_RESET_BASE + CRC_RST_DEV_L_CLR);
+}
+
+/* stop all internal and external clocks to the main CPU complex */
+static void stop_maincomplex_clocks(int num_cores)
+{
+ u32 reg;
+ int i;
+
+ reg = readl(TEGRA_CLK_RESET_BASE + CRC_CLK_CPU_CMPLX);
+ for (i = 0; i < num_cores; i++) {
+ reg |= 0x1 << (8 + i);
+ }
+ writel(reg, TEGRA_CLK_RESET_BASE + CRC_CLK_CPU_CMPLX);
+
+ reg = readl(TEGRA_CLK_RESET_BASE + CRC_CLK_OUT_ENB_L);
+ reg &= ~CRC_CLK_OUT_ENB_L_CPU;
+ writel(reg, TEGRA_CLK_RESET_BASE + CRC_CLK_OUT_ENB_L);
+}
+
+struct pll_config {
+ u16 divn;
+ u16 divm;
+ u16 divp;
+ u16 cpcon;
+};
+
+static struct pll_config pllx_config_table[][4] = {
+ {
+ {1000, 13, 0, 12}, /* OSC 13.0 MHz */
+ {625, 12, 0, 8 }, /* OSC 19.2 MHz */
+ {1000, 12, 0, 12}, /* OSC 12.0 MHz */
+ {1000, 26, 0, 12}, /* OSC 26.0 MHz */
+ }, /* TEGRA 20 */
+};
+
+static void init_pllx(void)
+{
+ struct pll_config *conf;
+ enum tegra_chiptype chiptype;
+ u8 osc_freq;
+ u32 reg;
+
+ /* If PLLX is already enabled, just return */
+ if (readl(TEGRA_CLK_RESET_BASE + CRC_PLLX_BASE) & CRC_PLLX_BASE_ENABLE)
+ return;
+
+ chiptype = tegra_get_chiptype();
+ if (chiptype < 0)
+ BUG();
+
+ osc_freq = (readl(TEGRA_CLK_RESET_BASE + CRC_OSC_CTRL) &
+ CRC_OSC_CTRL_OSC_FREQ_MASK) >> CRC_OSC_CTRL_OSC_FREQ_SHIFT;
+
+ conf = &pllx_config_table[chiptype][osc_freq];
+
+ /* set PLL bypass and frequency parameters */
+ reg = CRC_PLLX_BASE_BYPASS;
+ reg |= (conf->divm << CRC_PLLX_BASE_DIVM_SHIFT) &
+ CRC_PLLX_BASE_DIVM_MASK;
+ reg |= (conf->divn << CRC_PLLX_BASE_DIVN_SHIFT) &
+ CRC_PLLX_BASE_DIVN_MASK;
+ reg |= (conf->divp << CRC_PLLX_BASE_DIVP_SHIFT) &
+ CRC_PLLX_BASE_DIVP_MASK;
+ writel(reg, TEGRA_CLK_RESET_BASE + CRC_PLLX_BASE);
+
+ /* set chargepump parameters */
+ reg = (conf->cpcon << CRC_PLLX_MISC_CPCON_SHIFT) &
+ CRC_PLLX_MISC_CPCON_MASK;
+ if (conf->divn > 600)
+ reg |= CRC_PLLX_MISC_DCCON;
+ writel(reg, TEGRA_CLK_RESET_BASE + CRC_PLLX_MISC);
+
+ /* enable PLL and disable bypass */
+ reg = readl(TEGRA_CLK_RESET_BASE + CRC_PLLX_BASE);
+ reg |= CRC_PLLX_BASE_ENABLE;
+ reg &= ~CRC_PLLX_BASE_BYPASS;
+ writel(reg, TEGRA_CLK_RESET_BASE + CRC_PLLX_BASE);
+
+ /* enable PLL lock */
+ reg = readl(TEGRA_CLK_RESET_BASE + CRC_PLLX_MISC);
+ reg |= CRC_PLLX_MISC_LOCK_ENABLE;
+ writel(reg, TEGRA_CLK_RESET_BASE + CRC_PLLX_MISC);
+}
+
+/* start internal and external clocks to core 0 of the main CPU complex */
+static void start_cpu0_clocks(void)
+{
+ u32 reg;
+
+ /* setup PLLX */
+ init_pllx();
+
+ /* setup super CLK */
+ writel(CRC_SCLK_BURST_POLICY_SYS_STATE_RUN <<
+ CRC_SCLK_BURST_POLICY_SYS_STATE_SHIFT,
+ TEGRA_CLK_RESET_BASE + CRC_SCLK_BURST_POLICY);
+ writel(CRC_SUPER_SDIV_ENB, TEGRA_CLK_RESET_BASE + CRC_SUPER_SCLK_DIV);
+
+ /* deassert clock stop for cpu 0 */
+ reg = readl(TEGRA_CLK_RESET_BASE + CRC_CLK_CPU_CMPLX);
+ reg &= ~CRC_CLK_CPU_CMPLX_CPU0_CLK_STP;
+ writel(reg, TEGRA_CLK_RESET_BASE + CRC_CLK_CPU_CMPLX);
+
+ /* enable main CPU complex clock */
+ reg = readl(TEGRA_CLK_RESET_BASE + CRC_CLK_OUT_ENB_L);
+ reg |= CRC_CLK_OUT_ENB_L_CPU;
+ writel(reg, TEGRA_CLK_RESET_BASE + CRC_CLK_OUT_ENB_L);
+}
+
+static void maincomplex_powerup(void)
+{
+ u32 reg;
+
+ if (!(readl(TEGRA_PMC_BASE + PMC_PWRGATE_STATUS) &
+ PMC_PWRGATE_STATUS_CPU)) {
+ writel(PMC_PWRGATE_TOGGLE_START | PMC_PWRGATE_TOGGLE_PARTID_CPU,
+ TEGRA_PMC_BASE + PMC_PWRGATE_TOGGLE);
+
+ while (!(readl(TEGRA_PMC_BASE + PMC_PWRGATE_STATUS) &
+ PMC_PWRGATE_STATUS_CPU));
+
+ reg = readl(TEGRA_PMC_BASE + PMC_REMOVE_CLAMPING_CMD);
+ reg |= PMC_REMOVE_CLAMPING_CMD_CPU;
+ writel(reg, TEGRA_PMC_BASE + PMC_REMOVE_CLAMPING_CMD);
+ }
+}
+void barebox_arm_reset_vector(void)
+{
+ int num_cores;
+
+ /* minimal initialization, OK for both ARMv4 and ARMv7 */
+ tegra_cpu_lowlevel_setup();
+
+ /*
+ * If we are already running on the main CPU complex jump straight
+ * to the maincomplex entry point.
+ */
+ if (tegra_cpu_is_maincomplex())
+ tegra_maincomplex_entry();
+
+ /* get the number of cores in the main CPU complex of the current SoC */
+ num_cores = tegra_get_num_cores();
+ if (!num_cores)
+ BUG();
+
+ /* bring down main CPU complex (this may be a warm boot) */
+ enable_maincomplex_powerrail();
+ assert_maincomplex_reset(num_cores);
+ stop_maincomplex_clocks(num_cores);
+
+ /* set start address for the main CPU complex processors */
+ writel(barebox_arm_head, TEGRA_EXCEPTION_VECTORS_BASE + 0x100);
+
+ /* bring up main CPU complex */
+ start_cpu0_clocks();
+ maincomplex_powerup();
+ deassert_cpu0_reset();
+
+ /* assert AVP reset to stop execution here */
+ writel(CRC_RST_DEV_L_SET_COP, TEGRA_CLK_RESET_BASE + CRC_RST_DEV_L_SET);
+
+ unreachable();
+}
diff --git a/arch/arm/mach-tegra/tegra_maincomplex_init.c b/arch/arm/mach-tegra/tegra_maincomplex_init.c
new file mode 100644
index 0000000..dea9c91
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra_maincomplex_init.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <common.h>
+#include <sizes.h>
+#include <asm/barebox-arm-head.h>
+#include <asm/barebox-arm.h>
+#include <mach/lowlevel.h>
+
+void tegra_maincomplex_entry(void)
+{
+ uint32_t rambase, ramsize;
+
+ arm_cpu_lowlevel_init();
+
+ switch (tegra_get_chiptype()) {
+ case TEGRA20:
+ rambase = 0x0;
+ ramsize = tegra20_get_ramsize();
+ break;
+ default:
+ /* If we don't know the chiptype, better bail out */
+ BUG();
+ }
+
+ /*
+ * The standard load address for Tegra systems is 0x10800 which means
+ * the barebox binary will always be below the malloc area for all
+ * reasonable malloc area sizes. We offset the RAM base address by 8MB
+ * to pretend barebox is in another bank.
+ */
+ barebox_arm_entry(rambase + SZ_8M, ramsize - SZ_8M, 0);
+}
--
1.8.1.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v4 11/13] tegra: add generic debug UART support
2013-04-10 9:14 [PATCH v4 01/13] tegra: pull in iomap.h from the Linux kernel Lucas Stach
` (8 preceding siblings ...)
2013-04-10 9:14 ` [PATCH v4 10/13] tegra: add common lowlevel startup Lucas Stach
@ 2013-04-10 9:14 ` Lucas Stach
2013-04-10 20:52 ` antonynpavlov
2013-04-10 9:14 ` [PATCH v4 12/13] tegra: add generic meminit Lucas Stach
2013-04-10 9:14 ` [PATCH v4 13/13] tegra: add GPIO controller driver Lucas Stach
11 siblings, 1 reply; 15+ messages in thread
From: Lucas Stach @ 2013-04-10 9:14 UTC (permalink / raw)
To: barebox
ODMdata tells us which UART to use for debugging purposes. This is
agreed upon in both the upstream Linux kernel and U-Boot, so do it the
same way in barebox.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
v4:
- fix rebase error
- provide Kconfig option to ovveride ODMdata
---
arch/arm/boards/toshiba-ac100/Makefile | 1 -
arch/arm/boards/toshiba-ac100/serial.c | 39 --------------------
arch/arm/configs/toshiba_ac100_defconfig | 1 +
arch/arm/mach-tegra/Kconfig | 33 +++++++++++++++++
arch/arm/mach-tegra/Makefile | 1 +
arch/arm/mach-tegra/include/mach/lowlevel.h | 34 +++++++++++++++++
arch/arm/mach-tegra/tegra20.c | 57 +++++++++++++++++++++++++++++
7 files changed, 126 insertions(+), 40 deletions(-)
delete mode 100644 arch/arm/boards/toshiba-ac100/serial.c
create mode 100644 arch/arm/mach-tegra/tegra20.c
diff --git a/arch/arm/boards/toshiba-ac100/Makefile b/arch/arm/boards/toshiba-ac100/Makefile
index 9e14763..dcfc293 100644
--- a/arch/arm/boards/toshiba-ac100/Makefile
+++ b/arch/arm/boards/toshiba-ac100/Makefile
@@ -1,2 +1 @@
obj-y += board.o
-obj-$(CONFIG_DRIVER_SERIAL_NS16550) += serial.o
diff --git a/arch/arm/boards/toshiba-ac100/serial.c b/arch/arm/boards/toshiba-ac100/serial.c
deleted file mode 100644
index 880270d..0000000
--- a/arch/arm/boards/toshiba-ac100/serial.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2011 Antony Pavlov <antonynpavlov@gmail.com>
- *
- * This file is part of barebox.
- * See file CREDITS for list of people who contributed to this project.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <common.h>
-#include <types.h>
-#include <driver.h>
-#include <init.h>
-#include <ns16550.h>
-#include <asm/io.h>
-#include <asm/common.h>
-#include <mach/iomap.h>
-
-static struct NS16550_plat serial_plat = {
- .clock = 0x75 * 115200 * 16 /* MODE_X_DIV */,
- .shift = 2,
-};
-
-static int ac100_serial_console_init(void)
-{
- /* Register the serial port */
- add_ns16550_device(DEVICE_ID_DYNAMIC, TEGRA_UARTA_BASE, 8 << serial_plat.shift,
- IORESOURCE_MEM_8BIT, &serial_plat);
-
- return 0;
-}
-console_initcall(ac100_serial_console_init);
diff --git a/arch/arm/configs/toshiba_ac100_defconfig b/arch/arm/configs/toshiba_ac100_defconfig
index 6f7011b..1903910 100644
--- a/arch/arm/configs/toshiba_ac100_defconfig
+++ b/arch/arm/configs/toshiba_ac100_defconfig
@@ -1,5 +1,6 @@
CONFIG_BUILTIN_DTB_NAME="tegra20-paz00"
CONFIG_ARCH_TEGRA=y
+CONFIG_TEGRA_UART_A=y
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
CONFIG_TEXT_BASE=0x01000000
CONFIG_BROKEN=y
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 2f15b27..965e7ab 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -8,6 +8,39 @@ config ARCH_TEGRA_2x_SOC
endchoice
+choice
+ prompt "Tegra debug UART"
+ help
+ This is the first serial console that gets activated by barebox.
+ Normally each board vendor should program a valid debug UART into
+ the ODMdata section of the boot configuration table, so it's a
+ reasonably good bet to use that.
+ If you know your ODMdata is broken, or you don't wish to activate
+ any serial console at all you can override the default here.
+
+config TEGRA_UART_ODMDATA
+ bool "ODMdata defined UART"
+
+config TEGRA_UART_A
+ bool "UART A"
+
+config TEGRA_UART_B
+ bool "UART B"
+
+config TEGRA_UART_C
+ bool "UART C"
+
+config TEGRA_UART_D
+ bool "UART D"
+
+config TEGRA_UART_E
+ bool "UART E"
+
+config TEGRA_UART_NONE
+ bool "None"
+
+endchoice
+
# ---------------------------------------------------------
if ARCH_TEGRA_2x_SOC
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 0807af6..f9c771f 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -1,6 +1,7 @@
CFLAGS_tegra_avp_init.o := -mcpu=arm7tdmi -march=armv4t
lwl-y += tegra_avp_init.o
lwl-y += tegra_maincomplex_init.o
+obj-y += tegra20.o
obj-y += tegra20-car.o
obj-y += tegra20-pmc.o
obj-y += tegra20-timer.o
diff --git a/arch/arm/mach-tegra/include/mach/lowlevel.h b/arch/arm/mach-tegra/include/mach/lowlevel.h
index bd1a8db..a24b8c2 100644
--- a/arch/arm/mach-tegra/include/mach/lowlevel.h
+++ b/arch/arm/mach-tegra/include/mach/lowlevel.h
@@ -35,6 +35,10 @@
#define T20_ODMDATA_RAMSIZE_SHIFT 28
#define T20_ODMDATA_RAMSIZE_MASK (3 << T20_ODMDATA_RAMSIZE_SHIFT)
+#define T20_ODMDATA_UARTTYPE_SHIFT 18
+#define T20_ODMDATA_UARTTYPE_MASK (3 << T20_ODMDATA_UARTTYPE_SHIFT)
+#define T20_ODMDATA_UARTID_SHIFT 15
+#define T20_ODMDATA_UARTID_MASK (7 << T20_ODMDATA_UARTID_SHIFT)
static inline u32 tegra_get_odmdata(void)
{
@@ -109,5 +113,35 @@ static inline uint32_t tegra20_get_ramsize(void)
}
}
+static long uart_id_to_base[] = {
+ TEGRA_UARTA_BASE,
+ TEGRA_UARTB_BASE,
+ TEGRA_UARTC_BASE,
+ TEGRA_UARTD_BASE,
+ TEGRA_UARTE_BASE,
+};
+
+static inline long tegra20_get_debuguart_base(void)
+{
+ u32 odmdata;
+ int id;
+
+ odmdata = tegra_get_odmdata();
+
+ /*
+ * Get type, we accept both "2" and "3", as they both demark a UART,
+ * depending on the board type.
+ */
+ if (!(((odmdata & T20_ODMDATA_UARTTYPE_MASK) >>
+ T20_ODMDATA_UARTTYPE_SHIFT) & 0x2))
+ return 0;
+
+ id = (odmdata & T20_ODMDATA_UARTID_MASK) >> T20_ODMDATA_UARTID_SHIFT;
+ if (id > ARRAY_SIZE(uart_id_to_base))
+ return 0;
+
+ return uart_id_to_base[id];
+}
+
/* reset vector for the main CPU complex */
void tegra_maincomplex_entry(void);
diff --git a/arch/arm/mach-tegra/tegra20.c b/arch/arm/mach-tegra/tegra20.c
new file mode 100644
index 0000000..1a09e55
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra20.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <ns16550.h>
+#include <mach/iomap.h>
+#include <mach/lowlevel.h>
+
+static struct NS16550_plat debug_uart = {
+ .clock = 216000000, /* pll_p rate */
+ .shift = 2,
+};
+
+static int tegra20_add_debug_console(void)
+{
+ unsigned long base = 0;
+
+ /* figure out which UART to use */
+#if defined(CONFIG_TEGRA_UART_NONE)
+ return 0;
+#elif defined(CONFIG_TEGRA_UART_ODMDATA)
+ base = tegra20_get_debuguart_base();
+#elif defined(CONFIG_TEGRA_UART_A)
+ base = TEGRA_UARTA_BASE;
+#elif defined(CONFIG_TEGRA_UART_B)
+ base = TEGRA_UARTB_BASE;
+#elif defined(CONFIG_TEGRA_UART_C)
+ base = TEGRA_UARTC_BASE;
+#elif defined(CONFIG_TEGRA_UART_D)
+ base = TEGRA_UARTD_BASE;
+#elif defined(CONFIG_TEGRA_UART_E)
+ base = TEGRA_UARTE_BASE;
+#endif
+
+ if (!base)
+ return -ENODEV;
+
+ add_ns16550_device(DEVICE_ID_DYNAMIC, base, 8 << debug_uart.shift,
+ IORESOURCE_MEM_8BIT, &debug_uart);
+
+ return 0;
+}
+console_initcall(tegra20_add_debug_console);
--
1.8.1.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 11/13] tegra: add generic debug UART support
2013-04-10 9:14 ` [PATCH v4 11/13] tegra: add generic debug UART support Lucas Stach
@ 2013-04-10 20:52 ` antonynpavlov
0 siblings, 0 replies; 15+ messages in thread
From: antonynpavlov @ 2013-04-10 20:52 UTC (permalink / raw)
To: Lucas Stach; +Cc: barebox
On Wed, 10 Apr 2013 11:14:53 +0200
Lucas Stach <dev@lynxeye.de> wrote:
> ODMdata tells us which UART to use for debugging purposes. This is
> agreed upon in both the upstream Linux kernel and U-Boot, so do it the
> same way in barebox.
>
> Signed-off-by: Lucas Stach <dev@lynxeye.de>
> ---
> v4:
> - fix rebase error
> - provide Kconfig option to ovveride ODMdata
> ---
> arch/arm/boards/toshiba-ac100/Makefile | 1 -
> arch/arm/boards/toshiba-ac100/serial.c | 39 --------------------
> arch/arm/configs/toshiba_ac100_defconfig | 1 +
> arch/arm/mach-tegra/Kconfig | 33 +++++++++++++++++
> arch/arm/mach-tegra/Makefile | 1 +
> arch/arm/mach-tegra/include/mach/lowlevel.h | 34 +++++++++++++++++
> arch/arm/mach-tegra/tegra20.c | 57 +++++++++++++++++++++++++++++
> 7 files changed, 126 insertions(+), 40 deletions(-)
> delete mode 100644 arch/arm/boards/toshiba-ac100/serial.c
> create mode 100644 arch/arm/mach-tegra/tegra20.c
>
> diff --git a/arch/arm/boards/toshiba-ac100/Makefile b/arch/arm/boards/toshiba-ac100/Makefile
> index 9e14763..dcfc293 100644
> --- a/arch/arm/boards/toshiba-ac100/Makefile
> +++ b/arch/arm/boards/toshiba-ac100/Makefile
> @@ -1,2 +1 @@
> obj-y += board.o
> -obj-$(CONFIG_DRIVER_SERIAL_NS16550) += serial.o
> diff --git a/arch/arm/boards/toshiba-ac100/serial.c b/arch/arm/boards/toshiba-ac100/serial.c
> deleted file mode 100644
> index 880270d..0000000
> --- a/arch/arm/boards/toshiba-ac100/serial.c
> +++ /dev/null
> @@ -1,39 +0,0 @@
> -/*
> - * Copyright (C) 2011 Antony Pavlov <antonynpavlov@gmail.com>
> - *
> - * This file is part of barebox.
> - * See file CREDITS for list of people who contributed to this project.
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2
> - * as published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> - * GNU General Public License for more details.
> - */
> -
> -#include <common.h>
> -#include <types.h>
> -#include <driver.h>
> -#include <init.h>
> -#include <ns16550.h>
> -#include <asm/io.h>
> -#include <asm/common.h>
> -#include <mach/iomap.h>
> -
> -static struct NS16550_plat serial_plat = {
> - .clock = 0x75 * 115200 * 16 /* MODE_X_DIV */,
> - .shift = 2,
> -};
> -
> -static int ac100_serial_console_init(void)
> -{
> - /* Register the serial port */
> - add_ns16550_device(DEVICE_ID_DYNAMIC, TEGRA_UARTA_BASE, 8 << serial_plat.shift,
> - IORESOURCE_MEM_8BIT, &serial_plat);
> -
> - return 0;
> -}
> -console_initcall(ac100_serial_console_init);
> diff --git a/arch/arm/configs/toshiba_ac100_defconfig b/arch/arm/configs/toshiba_ac100_defconfig
> index 6f7011b..1903910 100644
> --- a/arch/arm/configs/toshiba_ac100_defconfig
> +++ b/arch/arm/configs/toshiba_ac100_defconfig
> @@ -1,5 +1,6 @@
> CONFIG_BUILTIN_DTB_NAME="tegra20-paz00"
> CONFIG_ARCH_TEGRA=y
> +CONFIG_TEGRA_UART_A=y
> CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
> CONFIG_TEXT_BASE=0x01000000
> CONFIG_BROKEN=y
> diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
> index 2f15b27..965e7ab 100644
> --- a/arch/arm/mach-tegra/Kconfig
> +++ b/arch/arm/mach-tegra/Kconfig
> @@ -8,6 +8,39 @@ config ARCH_TEGRA_2x_SOC
>
> endchoice
>
> +choice
> + prompt "Tegra debug UART"
> + help
> + This is the first serial console that gets activated by barebox.
> + Normally each board vendor should program a valid debug UART into
> + the ODMdata section of the boot configuration table, so it's a
> + reasonably good bet to use that.
> + If you know your ODMdata is broken, or you don't wish to activate
> + any serial console at all you can override the default here.
> +
> +config TEGRA_UART_ODMDATA
> + bool "ODMdata defined UART"
> +
> +config TEGRA_UART_A
> + bool "UART A"
> +
> +config TEGRA_UART_B
> + bool "UART B"
> +
> +config TEGRA_UART_C
> + bool "UART C"
> +
> +config TEGRA_UART_D
> + bool "UART D"
> +
> +config TEGRA_UART_E
> + bool "UART E"
> +
> +config TEGRA_UART_NONE
> + bool "None"
> +
> +endchoice
> +
> # ---------------------------------------------------------
>
> if ARCH_TEGRA_2x_SOC
> diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
> index 0807af6..f9c771f 100644
> --- a/arch/arm/mach-tegra/Makefile
> +++ b/arch/arm/mach-tegra/Makefile
> @@ -1,6 +1,7 @@
> CFLAGS_tegra_avp_init.o := -mcpu=arm7tdmi -march=armv4t
> lwl-y += tegra_avp_init.o
> lwl-y += tegra_maincomplex_init.o
> +obj-y += tegra20.o
> obj-y += tegra20-car.o
> obj-y += tegra20-pmc.o
> obj-y += tegra20-timer.o
> diff --git a/arch/arm/mach-tegra/include/mach/lowlevel.h b/arch/arm/mach-tegra/include/mach/lowlevel.h
> index bd1a8db..a24b8c2 100644
> --- a/arch/arm/mach-tegra/include/mach/lowlevel.h
> +++ b/arch/arm/mach-tegra/include/mach/lowlevel.h
> @@ -35,6 +35,10 @@
>
> #define T20_ODMDATA_RAMSIZE_SHIFT 28
> #define T20_ODMDATA_RAMSIZE_MASK (3 << T20_ODMDATA_RAMSIZE_SHIFT)
> +#define T20_ODMDATA_UARTTYPE_SHIFT 18
> +#define T20_ODMDATA_UARTTYPE_MASK (3 << T20_ODMDATA_UARTTYPE_SHIFT)
> +#define T20_ODMDATA_UARTID_SHIFT 15
> +#define T20_ODMDATA_UARTID_MASK (7 << T20_ODMDATA_UARTID_SHIFT)
>
> static inline u32 tegra_get_odmdata(void)
> {
> @@ -109,5 +113,35 @@ static inline uint32_t tegra20_get_ramsize(void)
> }
> }
>
> +static long uart_id_to_base[] = {
> + TEGRA_UARTA_BASE,
> + TEGRA_UARTB_BASE,
> + TEGRA_UARTC_BASE,
> + TEGRA_UARTD_BASE,
> + TEGRA_UARTE_BASE,
> +};
> +
> +static inline long tegra20_get_debuguart_base(void)
> +{
> + u32 odmdata;
> + int id;
> +
> + odmdata = tegra_get_odmdata();
> +
> + /*
> + * Get type, we accept both "2" and "3", as they both demark a UART,
> + * depending on the board type.
> + */
> + if (!(((odmdata & T20_ODMDATA_UARTTYPE_MASK) >>
> + T20_ODMDATA_UARTTYPE_SHIFT) & 0x2))
> + return 0;
> +
> + id = (odmdata & T20_ODMDATA_UARTID_MASK) >> T20_ODMDATA_UARTID_SHIFT;
> + if (id > ARRAY_SIZE(uart_id_to_base))
> + return 0;
> +
> + return uart_id_to_base[id];
> +}
> +
> /* reset vector for the main CPU complex */
> void tegra_maincomplex_entry(void);
> diff --git a/arch/arm/mach-tegra/tegra20.c b/arch/arm/mach-tegra/tegra20.c
> new file mode 100644
> index 0000000..1a09e55
> --- /dev/null
> +++ b/arch/arm/mach-tegra/tegra20.c
> @@ -0,0 +1,57 @@
> +/*
> + * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <ns16550.h>
> +#include <mach/iomap.h>
> +#include <mach/lowlevel.h>
> +
> +static struct NS16550_plat debug_uart = {
> + .clock = 216000000, /* pll_p rate */
> + .shift = 2,
> +};
> +
> +static int tegra20_add_debug_console(void)
> +{
> + unsigned long base = 0;
> +
> + /* figure out which UART to use */
> +#if defined(CONFIG_TEGRA_UART_NONE)
There is a practice to avoid preprocessor directives in the .c-files
for checking CONFIG_* options.
Use the IS_ENABLED() macro instead.
> + return 0;
> +#elif defined(CONFIG_TEGRA_UART_ODMDATA)
> + base = tegra20_get_debuguart_base();
> +#elif defined(CONFIG_TEGRA_UART_A)
> + base = TEGRA_UARTA_BASE;
> +#elif defined(CONFIG_TEGRA_UART_B)
> + base = TEGRA_UARTB_BASE;
> +#elif defined(CONFIG_TEGRA_UART_C)
> + base = TEGRA_UARTC_BASE;
> +#elif defined(CONFIG_TEGRA_UART_D)
> + base = TEGRA_UARTD_BASE;
> +#elif defined(CONFIG_TEGRA_UART_E)
> + base = TEGRA_UARTE_BASE;
> +#endif
> +
> + if (!base)
> + return -ENODEV;
> +
> + add_ns16550_device(DEVICE_ID_DYNAMIC, base, 8 << debug_uart.shift,
> + IORESOURCE_MEM_8BIT, &debug_uart);
> +
> + return 0;
> +}
> +console_initcall(tegra20_add_debug_console);
> --
> 1.8.1.2
>
--
--
Best regards,
Antony Pavlov
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v4 12/13] tegra: add generic meminit
2013-04-10 9:14 [PATCH v4 01/13] tegra: pull in iomap.h from the Linux kernel Lucas Stach
` (9 preceding siblings ...)
2013-04-10 9:14 ` [PATCH v4 11/13] tegra: add generic debug UART support Lucas Stach
@ 2013-04-10 9:14 ` Lucas Stach
2013-04-10 9:14 ` [PATCH v4 13/13] tegra: add GPIO controller driver Lucas Stach
11 siblings, 0 replies; 15+ messages in thread
From: Lucas Stach @ 2013-04-10 9:14 UTC (permalink / raw)
To: barebox
ODMdata tells us how much RAM is installed, so no need to define this at
the board level.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
arch/arm/boards/toshiba-ac100/board.c | 8 --------
arch/arm/mach-tegra/tegra20.c | 9 +++++++++
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/arch/arm/boards/toshiba-ac100/board.c b/arch/arm/boards/toshiba-ac100/board.c
index 0eb85c5..51232ef 100644
--- a/arch/arm/boards/toshiba-ac100/board.c
+++ b/arch/arm/boards/toshiba-ac100/board.c
@@ -23,14 +23,6 @@
#include <usb/ehci.h>
#include <mach/iomap.h>
-static int ac100_mem_init(void)
-{
- arm_add_mem_device("ram0", 0x0, SZ_512M);
-
- return 0;
-}
-mem_initcall(ac100_mem_init);
-
static struct ehci_platform_data ehci_pdata = {
.flags = EHCI_HAS_TT,
};
diff --git a/arch/arm/mach-tegra/tegra20.c b/arch/arm/mach-tegra/tegra20.c
index 1a09e55..b06ae98 100644
--- a/arch/arm/mach-tegra/tegra20.c
+++ b/arch/arm/mach-tegra/tegra20.c
@@ -17,6 +17,7 @@
#include <common.h>
#include <init.h>
#include <ns16550.h>
+#include <asm/memory.h>
#include <mach/iomap.h>
#include <mach/lowlevel.h>
@@ -55,3 +56,11 @@ static int tegra20_add_debug_console(void)
return 0;
}
console_initcall(tegra20_add_debug_console);
+
+static int tegra20_mem_init(void)
+{
+ arm_add_mem_device("ram0", 0x0, tegra20_get_ramsize());
+
+ return 0;
+}
+mem_initcall(tegra20_mem_init);
--
1.8.1.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v4 13/13] tegra: add GPIO controller driver
2013-04-10 9:14 [PATCH v4 01/13] tegra: pull in iomap.h from the Linux kernel Lucas Stach
` (10 preceding siblings ...)
2013-04-10 9:14 ` [PATCH v4 12/13] tegra: add generic meminit Lucas Stach
@ 2013-04-10 9:14 ` Lucas Stach
2013-04-10 20:46 ` antonynpavlov
11 siblings, 1 reply; 15+ messages in thread
From: Lucas Stach @ 2013-04-10 9:14 UTC (permalink / raw)
To: barebox
Taken from the Linux kernel, simplified and reworked to match barebox.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
v4: remove Tegra 30 parts for now
---
arch/arm/Kconfig | 2 +
arch/arm/dts/tegra20.dtsi | 16 +++
arch/arm/mach-tegra/include/mach/gpio.h | 1 +
drivers/gpio/Kconfig | 7 ++
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-tegra.c | 214 ++++++++++++++++++++++++++++++++
6 files changed, 241 insertions(+)
create mode 100644 arch/arm/mach-tegra/include/mach/gpio.h
create mode 100644 drivers/gpio/gpio-tegra.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ed34d2c..0a4f821 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -142,6 +142,8 @@ config ARCH_TEGRA
select BUILTIN_DTB
select COMMON_CLK
select CLKDEV_LOOKUP
+ select GPIOLIB
+ select GPIO_TEGRA
select OFDEVICE
select OFTREE
diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
index 91858ec..b7d1e27 100644
--- a/arch/arm/dts/tegra20.dtsi
+++ b/arch/arm/dts/tegra20.dtsi
@@ -18,6 +18,22 @@
#clock-cells = <1>;
};
+ gpio: gpio {
+ compatible = "nvidia,tegra20-gpio";
+ reg = <0x6000d000 0x1000>;
+ interrupts = <0 32 0x04
+ 0 33 0x04
+ 0 34 0x04
+ 0 35 0x04
+ 0 55 0x04
+ 0 87 0x04
+ 0 89 0x04>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
pmc {
compatible = "nvidia,tegra20-pmc";
reg = <0x7000e400 0x400>;
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..306ab4c
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/gpio.h
@@ -0,0 +1 @@
+#include <asm-generic/gpio.h>
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ea07028..d5e0ed1 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -36,6 +36,13 @@ config GPIO_PL061
config GPIO_STMPE
depends on MFD_STMPE
bool "STMPE GPIO Expander"
+
+config GPIO_TEGRA
+ bool "GPIO support for the Tegra SoCs"
+ depends on ARCH_TEGRA
+ help
+ Say yes here to include the driver for the GPIO controller found on the
+ Tegra line of SoCs.
endmenu
endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 00acb68..5dcb6c8 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
+obj-$(CONFIG_GPIO_TEGRA) += gpio-tegra.o
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
new file mode 100644
index 0000000..227a12f
--- /dev/null
+++ b/drivers/gpio/gpio-tegra.c
@@ -0,0 +1,214 @@
+/* *
+ * Copyright (C) 2010 Erik Gilling <konkers@google.com>, Google, Inc
+ * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <common.h>
+#include <gpio.h>
+#include <init.h>
+#include <io.h>
+#include <linux/err.h>
+
+#define GPIO_BANK(x) ((x) >> 5)
+#define GPIO_PORT(x) (((x) >> 3) & 0x3)
+#define GPIO_BIT(x) ((x) & 0x7)
+
+#define GPIO_REG(x) (GPIO_BANK(x) * config->bank_stride + \
+ 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_ENB(x) (GPIO_REG(x) + 0x50)
+
+#define GPIO_MSK_CNF(x) (GPIO_REG(x) + config->upper_offset + 0x00)
+#define GPIO_MSK_OE(x) (GPIO_REG(x) + config->upper_offset + 0x10)
+#define GPIO_MSK_OUT(x) (GPIO_REG(x) + config->upper_offset + 0X20)
+
+struct tegra_gpio_bank {
+ int bank;
+ int irq;
+};
+
+struct tegra_gpio_soc_config {
+ u32 bank_stride;
+ u32 upper_offset;
+ u32 bank_count;
+};
+
+static void __iomem *gpio_base;
+static struct tegra_gpio_soc_config *config;
+
+static inline void tegra_gpio_writel(u32 val, u32 reg)
+{
+ writel(val, gpio_base + reg);
+}
+
+static inline u32 tegra_gpio_readl(u32 reg)
+{
+ return readl(gpio_base + reg);
+}
+
+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);
+ tegra_gpio_writel(val, reg);
+}
+
+static void tegra_gpio_enable(int gpio)
+{
+ tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1);
+}
+
+static void tegra_gpio_disable(int gpio)
+{
+ tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0);
+}
+
+static int tegra_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ return 0;
+}
+
+static void tegra_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ tegra_gpio_disable(offset);
+}
+
+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)
+{
+ /* If gpio is in output mode then read from the out value */
+ if ((tegra_gpio_readl(GPIO_OE(offset)) >> GPIO_BIT(offset)) & 1) {
+ printf("GPIO output mode\n");
+ return (tegra_gpio_readl(GPIO_OUT(offset)) >>
+ GPIO_BIT(offset)) & 0x1;
+ }
+
+ printf("GPIO input mode\n");
+ return (tegra_gpio_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);
+ tegra_gpio_enable(offset);
+ 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);
+ tegra_gpio_enable(offset);
+ return 0;
+}
+
+static struct gpio_ops tegra_gpio_ops = {
+ .request = tegra_gpio_request,
+ .free = tegra_gpio_free,
+ .direction_input = tegra_gpio_direction_input,
+ .direction_output = tegra_gpio_direction_output,
+ .get = tegra_gpio_get,
+ .set = tegra_gpio_set,
+};
+
+static struct gpio_chip tegra_gpio_chip = {
+ .ops = &tegra_gpio_ops,
+ .base = 0,
+};
+
+static int tegra_gpio_probe(struct device_d *dev)
+{
+ int i, j, ret;
+
+ ret = dev_get_drvdata(dev, (unsigned long *)&config);
+ if (ret) {
+ dev_err(dev, "dev_get_drvdata failed: %d\n", ret);
+ return ret;
+ }
+
+ gpio_base = dev_request_mem_region(dev, 0);
+ if (!gpio_base) {
+ dev_err(dev, "could not get memory region\n");
+ return -ENODEV;
+ }
+
+ for (i = 0; i < config->bank_count; i++) {
+ for (j = 0; j < 4; j++) {
+ int gpio = tegra_gpio_compose(i, j, 0);
+ tegra_gpio_writel(0x00, GPIO_INT_ENB(gpio));
+ }
+ }
+
+ tegra_gpio_chip.ngpio = config->bank_count * 32;
+ tegra_gpio_chip.dev = dev;
+
+ gpiochip_add(&tegra_gpio_chip);
+
+ return 0;
+}
+
+static struct tegra_gpio_soc_config tegra20_gpio_config = {
+ .bank_stride = 0x80,
+ .upper_offset = 0x800,
+ .bank_count = 7,
+};
+
+static struct platform_device_id tegra_gpio_ids[] = {
+ {
+ .name = "tegra20-gpio",
+ .driver_data = (unsigned long)&tegra20_gpio_config,
+ }, {
+ /* sentinel */
+ },
+};
+
+static __maybe_unused struct of_device_id tegra_gpio_dt_ids[] = {
+ {
+ .compatible = "nvidia,tegra20-gpio",
+ .data = (unsigned long)&tegra20_gpio_config
+ }, {
+ /* sentinel */
+ },
+};
+
+static struct driver_d tegra_gpio_driver = {
+ .name = "tegra-gpio",
+ .id_table = tegra_gpio_ids,
+ .of_compatible = DRV_OF_COMPAT(tegra_gpio_dt_ids),
+ .probe = tegra_gpio_probe,
+};
+
+static int __init tegra_gpio_init(void)
+{
+ return platform_driver_register(&tegra_gpio_driver);
+}
+coredevice_initcall(tegra_gpio_init);
--
1.8.1.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 13/13] tegra: add GPIO controller driver
2013-04-10 9:14 ` [PATCH v4 13/13] tegra: add GPIO controller driver Lucas Stach
@ 2013-04-10 20:46 ` antonynpavlov
0 siblings, 0 replies; 15+ messages in thread
From: antonynpavlov @ 2013-04-10 20:46 UTC (permalink / raw)
To: Lucas Stach; +Cc: barebox
On Wed, 10 Apr 2013 11:14:55 +0200
Lucas Stach <dev@lynxeye.de> wrote:
> Taken from the Linux kernel, simplified and reworked to match barebox.
>
> Signed-off-by: Lucas Stach <dev@lynxeye.de>
> ---
> v4: remove Tegra 30 parts for now
> ---
> arch/arm/Kconfig | 2 +
> arch/arm/dts/tegra20.dtsi | 16 +++
> arch/arm/mach-tegra/include/mach/gpio.h | 1 +
> drivers/gpio/Kconfig | 7 ++
> drivers/gpio/Makefile | 1 +
> drivers/gpio/gpio-tegra.c | 214 ++++++++++++++++++++++++++++++++
> 6 files changed, 241 insertions(+)
> create mode 100644 arch/arm/mach-tegra/include/mach/gpio.h
> create mode 100644 drivers/gpio/gpio-tegra.c
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index ed34d2c..0a4f821 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -142,6 +142,8 @@ config ARCH_TEGRA
> select BUILTIN_DTB
> select COMMON_CLK
> select CLKDEV_LOOKUP
> + select GPIOLIB
> + select GPIO_TEGRA
> select OFDEVICE
> select OFTREE
>
> diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
> index 91858ec..b7d1e27 100644
> --- a/arch/arm/dts/tegra20.dtsi
> +++ b/arch/arm/dts/tegra20.dtsi
> @@ -18,6 +18,22 @@
> #clock-cells = <1>;
> };
>
> + gpio: gpio {
> + compatible = "nvidia,tegra20-gpio";
> + reg = <0x6000d000 0x1000>;
> + interrupts = <0 32 0x04
> + 0 33 0x04
> + 0 34 0x04
> + 0 35 0x04
> + 0 55 0x04
> + 0 87 0x04
> + 0 89 0x04>;
> + #gpio-cells = <2>;
> + gpio-controller;
> + #interrupt-cells = <2>;
> + interrupt-controller;
> + };
> +
> pmc {
> compatible = "nvidia,tegra20-pmc";
> reg = <0x7000e400 0x400>;
> 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..306ab4c
> --- /dev/null
> +++ b/arch/arm/mach-tegra/include/mach/gpio.h
> @@ -0,0 +1 @@
> +#include <asm-generic/gpio.h>
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index ea07028..d5e0ed1 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -36,6 +36,13 @@ config GPIO_PL061
> config GPIO_STMPE
> depends on MFD_STMPE
> bool "STMPE GPIO Expander"
> +
> +config GPIO_TEGRA
> + bool "GPIO support for the Tegra SoCs"
> + depends on ARCH_TEGRA
> + help
> + Say yes here to include the driver for the GPIO controller found on the
> + Tegra line of SoCs.
> endmenu
>
> endif
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index 00acb68..5dcb6c8 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -4,3 +4,4 @@ obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
> obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
> obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
> obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
> +obj-$(CONFIG_GPIO_TEGRA) += gpio-tegra.o
> diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
> new file mode 100644
> index 0000000..227a12f
> --- /dev/null
> +++ b/drivers/gpio/gpio-tegra.c
> @@ -0,0 +1,214 @@
> +/* *
> + * Copyright (C) 2010 Erik Gilling <konkers@google.com>, Google, Inc
> + * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <common.h>
> +#include <gpio.h>
> +#include <init.h>
> +#include <io.h>
> +#include <linux/err.h>
> +
> +#define GPIO_BANK(x) ((x) >> 5)
> +#define GPIO_PORT(x) (((x) >> 3) & 0x3)
> +#define GPIO_BIT(x) ((x) & 0x7)
> +
> +#define GPIO_REG(x) (GPIO_BANK(x) * config->bank_stride + \
> + 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_ENB(x) (GPIO_REG(x) + 0x50)
> +
> +#define GPIO_MSK_CNF(x) (GPIO_REG(x) + config->upper_offset + 0x00)
> +#define GPIO_MSK_OE(x) (GPIO_REG(x) + config->upper_offset + 0x10)
> +#define GPIO_MSK_OUT(x) (GPIO_REG(x) + config->upper_offset + 0X20)
> +
> +struct tegra_gpio_bank {
> + int bank;
> + int irq;
> +};
> +
> +struct tegra_gpio_soc_config {
> + u32 bank_stride;
> + u32 upper_offset;
> + u32 bank_count;
> +};
> +
> +static void __iomem *gpio_base;
> +static struct tegra_gpio_soc_config *config;
The scripts/checkpatch.pl reports about formatting error here:
WARNING: please, no space before tabs
#175: FILE: drivers/gpio/gpio-tegra.c:53:
+static ^Istruct tegra_gpio_soc_config *config;$
> +
> +static inline void tegra_gpio_writel(u32 val, u32 reg)
> +{
> + writel(val, gpio_base + reg);
> +}
> +
> +static inline u32 tegra_gpio_readl(u32 reg)
> +{
> + return readl(gpio_base + reg);
> +}
> +
> +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);
> + tegra_gpio_writel(val, reg);
> +}
> +
> +static void tegra_gpio_enable(int gpio)
> +{
> + tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1);
> +}
> +
> +static void tegra_gpio_disable(int gpio)
> +{
> + tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0);
> +}
> +
> +static int tegra_gpio_request(struct gpio_chip *chip, unsigned offset)
> +{
> + return 0;
> +}
> +
> +static void tegra_gpio_free(struct gpio_chip *chip, unsigned offset)
> +{
> + tegra_gpio_disable(offset);
> +}
> +
> +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)
> +{
> + /* If gpio is in output mode then read from the out value */
> + if ((tegra_gpio_readl(GPIO_OE(offset)) >> GPIO_BIT(offset)) & 1) {
> + printf("GPIO output mode\n");
> + return (tegra_gpio_readl(GPIO_OUT(offset)) >>
> + GPIO_BIT(offset)) & 0x1;
> + }
> +
> + printf("GPIO input mode\n");
> + return (tegra_gpio_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);
> + tegra_gpio_enable(offset);
> + 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);
> + tegra_gpio_enable(offset);
> + return 0;
> +}
> +
> +static struct gpio_ops tegra_gpio_ops = {
> + .request = tegra_gpio_request,
> + .free = tegra_gpio_free,
> + .direction_input = tegra_gpio_direction_input,
> + .direction_output = tegra_gpio_direction_output,
> + .get = tegra_gpio_get,
> + .set = tegra_gpio_set,
> +};
> +
> +static struct gpio_chip tegra_gpio_chip = {
> + .ops = &tegra_gpio_ops,
> + .base = 0,
> +};
> +
> +static int tegra_gpio_probe(struct device_d *dev)
> +{
> + int i, j, ret;
> +
> + ret = dev_get_drvdata(dev, (unsigned long *)&config);
> + if (ret) {
> + dev_err(dev, "dev_get_drvdata failed: %d\n", ret);
> + return ret;
> + }
> +
> + gpio_base = dev_request_mem_region(dev, 0);
> + if (!gpio_base) {
> + dev_err(dev, "could not get memory region\n");
> + return -ENODEV;
> + }
> +
> + for (i = 0; i < config->bank_count; i++) {
> + for (j = 0; j < 4; j++) {
> + int gpio = tegra_gpio_compose(i, j, 0);
> + tegra_gpio_writel(0x00, GPIO_INT_ENB(gpio));
> + }
> + }
> +
> + tegra_gpio_chip.ngpio = config->bank_count * 32;
> + tegra_gpio_chip.dev = dev;
> +
> + gpiochip_add(&tegra_gpio_chip);
> +
> + return 0;
> +}
> +
> +static struct tegra_gpio_soc_config tegra20_gpio_config = {
> + .bank_stride = 0x80,
> + .upper_offset = 0x800,
> + .bank_count = 7,
> +};
> +
> +static struct platform_device_id tegra_gpio_ids[] = {
> + {
> + .name = "tegra20-gpio",
> + .driver_data = (unsigned long)&tegra20_gpio_config,
> + }, {
> + /* sentinel */
> + },
> +};
> +
> +static __maybe_unused struct of_device_id tegra_gpio_dt_ids[] = {
> + {
> + .compatible = "nvidia,tegra20-gpio",
> + .data = (unsigned long)&tegra20_gpio_config
> + }, {
> + /* sentinel */
> + },
> +};
> +
> +static struct driver_d tegra_gpio_driver = {
> + .name = "tegra-gpio",
> + .id_table = tegra_gpio_ids,
> + .of_compatible = DRV_OF_COMPAT(tegra_gpio_dt_ids),
> + .probe = tegra_gpio_probe,
> +};
> +
> +static int __init tegra_gpio_init(void)
> +{
> + return platform_driver_register(&tegra_gpio_driver);
> +}
> +coredevice_initcall(tegra_gpio_init);
> --
> 1.8.1.2
>
--
--
Best regards,
Antony Pavlov
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread