* [PATCH 0/9] arm/tegra: fuse cleanup and emc device tree support
@ 2011-12-23 0:17 Olof Johansson
[not found] ` <1324599468-12845-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
0 siblings, 1 reply; 45+ messages in thread
From: Olof Johansson @ 2011-12-23 0:17 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
This series does two things: It brings in some of the fuse/apb dma patches
that have previously been posted (but now completely refactored), and it adds
EMC table support to the device tree.
The bindings have been previously discused and have been modified accordingly to
the last agreements there.
Since there's some dependencies on the fuse rework, I'm a little lazy
and posting it as one series instead of two.
Comments welcome. I'm likely going to miss the 3.3 cut-offs on this but I still
want to reach closure on it and stage it for 3.4.
Thanks!
-Olof
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH 1/9] arm/tegra: Don't WARN_ON() for too early dma channel allocations
[not found] ` <1324599468-12845-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
@ 2011-12-23 0:17 ` Olof Johansson
2011-12-23 0:17 ` [PATCH 2/9] arm/tegra: use APB DMA for accessing APB devices Olof Johansson
` (7 subsequent siblings)
8 siblings, 0 replies; 45+ messages in thread
From: Olof Johansson @ 2011-12-23 0:17 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Olof Johansson
Since we'll do opportunistic allocations before the dma subsystem is
enabled we want just silent failures and retries instead.
Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
---
arch/arm/mach-tegra/dma.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c
index c0cf967..98b33c8 100644
--- a/arch/arm/mach-tegra/dma.c
+++ b/arch/arm/mach-tegra/dma.c
@@ -357,7 +357,7 @@ struct tegra_dma_channel *tegra_dma_allocate_channel(int mode)
int channel;
struct tegra_dma_channel *ch = NULL;
- if (WARN_ON(!tegra_dma_initialized))
+ if (!tegra_dma_initialized)
return NULL;
mutex_lock(&tegra_dma_lock);
--
1.7.8.GIT
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 2/9] arm/tegra: use APB DMA for accessing APB devices
[not found] ` <1324599468-12845-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2011-12-23 0:17 ` [PATCH 1/9] arm/tegra: Don't WARN_ON() for too early dma channel allocations Olof Johansson
@ 2011-12-23 0:17 ` Olof Johansson
[not found] ` <1324599468-12845-3-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2011-12-23 0:17 ` [PATCH 3/9] arm/tegra: fuse: use apbio dma for register access Olof Johansson
` (6 subsequent siblings)
8 siblings, 1 reply; 45+ messages in thread
From: Olof Johansson @ 2011-12-23 0:17 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Olof Johansson
Tegra2 hangs if APB registers are accessed from the cpu during an
apb dma operation. The workaround is to use apb dma to read/write the
registers instead.
There is a dependency loop between fuses, clocks, and APBDMA. If dma
is enabled, fuse reads must go through APBDMA to avoid corruption due
to a hw bug. APBDMA requires a clock to be enabled. Clocks must read
a fuse to determine allowable cpu frequencies.
Separate out the fuse DMA initialization, and allow the fuse read
and write functions to be called without using DMA before the DMA
initialization has been completed. Access to the fuses before APBDMA
is initialized won't hit the hardware bug because nothing else can be
using DMA.
Original fuse registar access code from Varun Wadekar
<vwadekar-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>, improved by Colin Cross <ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>
and later moved to separate driver by Jon Mayo <jmayo-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>.
Major refactoring/cleanup by Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>.
From: Jon Mayo <jmayo-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>.
Signed-off-by: Jon Mayo <jmayo-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>.
Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
---
arch/arm/mach-tegra/Makefile | 2 +-
arch/arm/mach-tegra/apbio.c | 140 ++++++++++++++++++++++++++++++++++++++++++
arch/arm/mach-tegra/apbio.h | 39 ++++++++++++
arch/arm/mach-tegra/dma.c | 2 +
4 files changed, 182 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/mach-tegra/apbio.c
create mode 100644 arch/arm/mach-tegra/apbio.h
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index e120ff5..23d15fb 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pinmux-tegra30-tables.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o
obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
-obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o
+obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o apbio.o
obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
obj-$(CONFIG_TEGRA_PCI) += pcie.o
obj-$(CONFIG_USB_SUPPORT) += usb_phy.o
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
new file mode 100644
index 0000000..7af9a4e
--- /dev/null
+++ b/arch/arm/mach-tegra/apbio.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2010 NVIDIA Corporation.
+ * 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/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include <linux/completion.h>
+#include <linux/sched.h>
+#include <linux/mutex.h>
+
+#include <mach/dma.h>
+#include <mach/iomap.h>
+
+#include "apbio.h"
+
+static DEFINE_MUTEX(tegra_apb_dma_lock);
+
+static struct tegra_dma_channel *tegra_apb_dma;
+static u32 *tegra_apb_bb;
+static dma_addr_t tegra_apb_bb_phys;
+static DECLARE_COMPLETION(tegra_apb_wait);
+
+bool tegra_apb_init(void)
+{
+ struct tegra_dma_channel *ch;
+
+ mutex_lock(&tegra_apb_dma_lock);
+
+ /* Check to see if we raced to setup */
+ if (tegra_apb_dma)
+ goto out;
+
+ ch = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT |
+ TEGRA_DMA_SHARED);
+
+ if (!ch)
+ goto out_fail;
+
+ tegra_apb_bb = dma_alloc_coherent(NULL, sizeof(u32),
+ &tegra_apb_bb_phys, GFP_KERNEL);
+ if (!tegra_apb_bb) {
+ pr_err("%s: can not allocate bounce buffer\n", __func__);
+ tegra_dma_free_channel(ch);
+ goto out_fail;
+ }
+
+ tegra_apb_dma = ch;
+out:
+ mutex_unlock(&tegra_apb_dma_lock);
+ return true;
+
+out_fail:
+ mutex_unlock(&tegra_apb_dma_lock);
+ return true;
+}
+
+static void apb_dma_complete(struct tegra_dma_req *req)
+{
+ complete(&tegra_apb_wait);
+}
+
+u32 tegra_apb_readl(unsigned long offset)
+{
+ struct tegra_dma_req req;
+ int ret;
+
+ if (!tegra_apb_dma && !tegra_apb_init())
+ return readl(IO_TO_VIRT(offset));
+
+ mutex_lock(&tegra_apb_dma_lock);
+ req.complete = apb_dma_complete;
+ req.to_memory = 1;
+ req.dest_addr = tegra_apb_bb_phys;
+ req.dest_bus_width = 32;
+ req.dest_wrap = 1;
+ req.source_addr = offset;
+ req.source_bus_width = 32;
+ req.source_wrap = 4;
+ req.req_sel = 0;
+ req.size = 4;
+
+ INIT_COMPLETION(tegra_apb_wait);
+
+ tegra_dma_enqueue_req(tegra_apb_dma, &req);
+
+ ret = wait_for_completion_timeout(&tegra_apb_wait,
+ msecs_to_jiffies(50));
+
+ if (WARN(ret == 0, "apb read dma timed out"))
+ *(u32 *)tegra_apb_bb = 0;
+
+ mutex_unlock(&tegra_apb_dma_lock);
+ return *((u32 *)tegra_apb_bb);
+}
+
+void tegra_apb_writel(u32 value, unsigned long offset)
+{
+ struct tegra_dma_req req;
+ int ret;
+
+ if (!tegra_apb_dma && !tegra_apb_init()) {
+ writel(value, IO_TO_VIRT(offset));
+ return;
+ }
+
+ mutex_lock(&tegra_apb_dma_lock);
+ *((u32 *)tegra_apb_bb) = value;
+ req.complete = apb_dma_complete;
+ req.to_memory = 0;
+ req.dest_addr = offset;
+ req.dest_wrap = 4;
+ req.dest_bus_width = 32;
+ req.source_addr = tegra_apb_bb_phys;
+ req.source_bus_width = 32;
+ req.source_wrap = 1;
+ req.req_sel = 0;
+ req.size = 4;
+
+ INIT_COMPLETION(tegra_apb_wait);
+
+ tegra_dma_enqueue_req(tegra_apb_dma, &req);
+
+ ret = wait_for_completion_timeout(&tegra_apb_wait,
+ msecs_to_jiffies(50));
+
+ mutex_unlock(&tegra_apb_dma_lock);
+}
diff --git a/arch/arm/mach-tegra/apbio.h b/arch/arm/mach-tegra/apbio.h
new file mode 100644
index 0000000..8b49e8c
--- /dev/null
+++ b/arch/arm/mach-tegra/apbio.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 NVIDIA Corporation.
+ * 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_APBIO_H
+#define __MACH_TEGRA_APBIO_H
+
+#ifdef CONFIG_TEGRA_SYSTEM_DMA
+
+u32 tegra_apb_readl(unsigned long offset);
+void tegra_apb_writel(u32 value, unsigned long offset);
+
+#else
+#include <asm/io.h>
+#include <mach/io.h>
+
+static inline u32 tegra_apb_readl(unsigned long offset)
+{
+ return readl(IO_TO_VIRT(offset));
+}
+
+static inline void tegra_apb_writel(u32 value, unsigned long offset)
+{
+ writel(value, IO_TO_VIRT(offset));
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c
index 98b33c8..122e467 100644
--- a/arch/arm/mach-tegra/dma.c
+++ b/arch/arm/mach-tegra/dma.c
@@ -33,6 +33,8 @@
#include <mach/iomap.h>
#include <mach/suspend.h>
+#include "apbio.h"
+
#define APB_DMA_GEN 0x000
#define GEN_ENABLE (1<<31)
--
1.7.8.GIT
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 3/9] arm/tegra: fuse: use apbio dma for register access
[not found] ` <1324599468-12845-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2011-12-23 0:17 ` [PATCH 1/9] arm/tegra: Don't WARN_ON() for too early dma channel allocations Olof Johansson
2011-12-23 0:17 ` [PATCH 2/9] arm/tegra: use APB DMA for accessing APB devices Olof Johansson
@ 2011-12-23 0:17 ` Olof Johansson
2011-12-23 0:17 ` [PATCH 4/9] arm/tegra: fuse: add functions to access chip revision Olof Johansson
` (5 subsequent siblings)
8 siblings, 0 replies; 45+ messages in thread
From: Olof Johansson @ 2011-12-23 0:17 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Olof Johansson
Use the apbio dma functions for accessing the fuse registers.
Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
---
arch/arm/mach-tegra/fuse.c | 20 ++++++++------------
1 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
index 1fa26d9..daf3f57 100644
--- a/arch/arm/mach-tegra/fuse.c
+++ b/arch/arm/mach-tegra/fuse.c
@@ -23,20 +23,16 @@
#include <mach/iomap.h>
#include "fuse.h"
+#include "apbio.h"
#define FUSE_UID_LOW 0x108
#define FUSE_UID_HIGH 0x10c
#define FUSE_SKU_INFO 0x110
#define FUSE_SPARE_BIT 0x200
-static inline u32 fuse_readl(unsigned long offset)
+static inline u32 tegra_fuse_readl(unsigned long offset)
{
- return readl(IO_TO_VIRT(TEGRA_FUSE_BASE + offset));
-}
-
-static inline void fuse_writel(u32 value, unsigned long offset)
-{
- writel(value, IO_TO_VIRT(TEGRA_FUSE_BASE + offset));
+ return tegra_apb_readl(TEGRA_FUSE_BASE + offset);
}
void tegra_init_fuse(void)
@@ -54,15 +50,15 @@ unsigned long long tegra_chip_uid(void)
{
unsigned long long lo, hi;
- lo = fuse_readl(FUSE_UID_LOW);
- hi = fuse_readl(FUSE_UID_HIGH);
+ lo = tegra_fuse_readl(FUSE_UID_LOW);
+ hi = tegra_fuse_readl(FUSE_UID_HIGH);
return (hi << 32ull) | lo;
}
int tegra_sku_id(void)
{
int sku_id;
- u32 reg = fuse_readl(FUSE_SKU_INFO);
+ u32 reg = tegra_fuse_readl(FUSE_SKU_INFO);
sku_id = reg & 0xFF;
return sku_id;
}
@@ -70,7 +66,7 @@ int tegra_sku_id(void)
int tegra_cpu_process_id(void)
{
int cpu_process_id;
- u32 reg = fuse_readl(FUSE_SPARE_BIT);
+ u32 reg = tegra_fuse_readl(FUSE_SPARE_BIT);
cpu_process_id = (reg >> 6) & 3;
return cpu_process_id;
}
@@ -78,7 +74,7 @@ int tegra_cpu_process_id(void)
int tegra_core_process_id(void)
{
int core_process_id;
- u32 reg = fuse_readl(FUSE_SPARE_BIT);
+ u32 reg = tegra_fuse_readl(FUSE_SPARE_BIT);
core_process_id = (reg >> 12) & 3;
return core_process_id;
}
--
1.7.8.GIT
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 4/9] arm/tegra: fuse: add functions to access chip revision
[not found] ` <1324599468-12845-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
` (2 preceding siblings ...)
2011-12-23 0:17 ` [PATCH 3/9] arm/tegra: fuse: use apbio dma for register access Olof Johansson
@ 2011-12-23 0:17 ` Olof Johansson
2011-12-23 10:47 ` Henning Heinold
[not found] ` <1324599468-12845-5-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2011-12-23 0:17 ` [PATCH 5/9] arm/tegra: fuse: add bct strapping reading Olof Johansson
` (4 subsequent siblings)
8 siblings, 2 replies; 45+ messages in thread
From: Olof Johansson @ 2011-12-23 0:17 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Olof Johansson
Add function to get chip revision, and print it out at boot time.
Restructure the fuse access to just use cached variables instead
of always reading the fuses, and export those variables directly
instead of using accessor functions.
Add a SKU ID table of currently known values.
Based on code originally by Colin Cross <ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>.
Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
---
arch/arm/mach-tegra/fuse.c | 80 +++++++++++++++++++++++------------
arch/arm/mach-tegra/fuse.h | 31 +++++++++++--
arch/arm/mach-tegra/tegra2_clocks.c | 2 +-
3 files changed, 80 insertions(+), 33 deletions(-)
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
index daf3f57..2ddede9 100644
--- a/arch/arm/mach-tegra/fuse.c
+++ b/arch/arm/mach-tegra/fuse.c
@@ -30,20 +30,70 @@
#define FUSE_SKU_INFO 0x110
#define FUSE_SPARE_BIT 0x200
+int tegra_sku_id;
+int tegra_cpu_process_id;
+int tegra_core_process_id;
+enum tegra_revision tegra_revision;
+
+static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
+ [TEGRA_REVISION_UNKNOWN] = "unknown",
+ [TEGRA_REVISION_A02] = "A02",
+ [TEGRA_REVISION_A03] = "A03",
+ [TEGRA_REVISION_A03p] = "A03 prime",
+ [TEGRA_REVISION_A04] = "A04",
+};
+
static inline u32 tegra_fuse_readl(unsigned long offset)
{
return tegra_apb_readl(TEGRA_FUSE_BASE + offset);
}
+static inline bool get_spare_fuse(int bit)
+{
+ return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4);
+}
+
+static enum tegra_revision tegra_get_revision(void)
+{
+ void __iomem *chip_id = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804;
+ u32 id = readl(chip_id);
+
+ switch ((id >> 16) & 0xf) {
+ case 2:
+ return TEGRA_REVISION_A02;
+ case 3:
+ if (get_spare_fuse(18) || get_spare_fuse(19))
+ return TEGRA_REVISION_A03p;
+ else
+ return TEGRA_REVISION_A03;
+ case 4:
+ return TEGRA_REVISION_A04;
+ default:
+ return TEGRA_REVISION_UNKNOWN;
+ }
+}
+
void tegra_init_fuse(void)
{
u32 reg = readl(IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
reg |= 1 << 28;
writel(reg, IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
- pr_info("Tegra SKU: %d CPU Process: %d Core Process: %d\n",
- tegra_sku_id(), tegra_cpu_process_id(),
- tegra_core_process_id());
+ reg = tegra_fuse_readl(FUSE_SKU_INFO);
+ tegra_sku_id = reg & 0xFF;
+
+ reg = tegra_fuse_readl(FUSE_SPARE_BIT);
+ tegra_cpu_process_id = (reg >> 6) & 3;
+
+ reg = tegra_fuse_readl(FUSE_SPARE_BIT);
+ tegra_core_process_id = (reg >> 12) & 3;
+
+ tegra_revision = tegra_get_revision();
+
+ pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
+ tegra_revision_name[tegra_get_revision()],
+ tegra_sku_id, tegra_cpu_process_id,
+ tegra_core_process_id);
}
unsigned long long tegra_chip_uid(void)
@@ -54,27 +104,3 @@ unsigned long long tegra_chip_uid(void)
hi = tegra_fuse_readl(FUSE_UID_HIGH);
return (hi << 32ull) | lo;
}
-
-int tegra_sku_id(void)
-{
- int sku_id;
- u32 reg = tegra_fuse_readl(FUSE_SKU_INFO);
- sku_id = reg & 0xFF;
- return sku_id;
-}
-
-int tegra_cpu_process_id(void)
-{
- int cpu_process_id;
- u32 reg = tegra_fuse_readl(FUSE_SPARE_BIT);
- cpu_process_id = (reg >> 6) & 3;
- return cpu_process_id;
-}
-
-int tegra_core_process_id(void)
-{
- int core_process_id;
- u32 reg = tegra_fuse_readl(FUSE_SPARE_BIT);
- core_process_id = (reg >> 12) & 3;
- return core_process_id;
-}
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
index 584b2e2..e418d40 100644
--- a/arch/arm/mach-tegra/fuse.h
+++ b/arch/arm/mach-tegra/fuse.h
@@ -1,6 +1,4 @@
/*
- * arch/arm/mach-tegra/fuse.c
- *
* Copyright (C) 2010 Google, Inc.
*
* Author:
@@ -17,8 +15,31 @@
*
*/
+#ifndef __MACH_TEGRA_FUSE_H
+#define __MACH_TEGRA_FUSE_H
+
+enum tegra_revision {
+ TEGRA_REVISION_UNKNOWN = 0,
+ TEGRA_REVISION_A02,
+ TEGRA_REVISION_A03,
+ TEGRA_REVISION_A03p,
+ TEGRA_REVISION_A04,
+ TEGRA_REVISION_MAX,
+};
+
+#define SKU_ID_T20 8
+#define SKU_ID_T25SE 20
+#define SKU_ID_AP25 23
+#define SKU_ID_T25 24
+#define SKU_ID_AP25E 27
+#define SKU_ID_T25E 28
+
+extern int tegra_sku_id;
+extern int tegra_cpu_process_id;
+extern int tegra_core_process_id;
+extern enum tegra_revision tegra_revision;
+
unsigned long long tegra_chip_uid(void);
-int tegra_sku_id(void);
-int tegra_cpu_process_id(void);
-int tegra_core_process_id(void);
void tegra_init_fuse(void);
+
+#endif
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index ff9e6b6..74d314fd 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -720,7 +720,7 @@ static void tegra2_pllx_clk_init(struct clk *c)
{
tegra2_pll_clk_init(c);
- if (tegra_sku_id() == 7)
+ if (tegra_sku_id == 7)
c->max_rate = 750000000;
}
--
1.7.8.GIT
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 5/9] arm/tegra: fuse: add bct strapping reading
[not found] ` <1324599468-12845-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
` (3 preceding siblings ...)
2011-12-23 0:17 ` [PATCH 4/9] arm/tegra: fuse: add functions to access chip revision Olof Johansson
@ 2011-12-23 0:17 ` Olof Johansson
2011-12-23 0:17 ` [PATCH 6/9] arm/tegra: emc: convert tegra2_emc to a platform driver Olof Johansson
` (3 subsequent siblings)
8 siblings, 0 replies; 45+ messages in thread
From: Olof Johansson @ 2011-12-23 0:17 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Olof Johansson
This is used by the memory setup code to pick the right memory
timing table, if needed.
Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
---
arch/arm/mach-tegra/fuse.c | 14 ++++++++++++++
arch/arm/mach-tegra/fuse.h | 2 ++
2 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
index 2ddede9..7fa8eb1 100644
--- a/arch/arm/mach-tegra/fuse.c
+++ b/arch/arm/mach-tegra/fuse.c
@@ -35,6 +35,17 @@ int tegra_cpu_process_id;
int tegra_core_process_id;
enum tegra_revision tegra_revision;
+/* The BCT to use at boot is specified by board straps that can be read
+ * through a APB misc register and decoded. 2 bits, i.e. 4 possible BCTs.
+ */
+int tegra_bct_strapping;
+
+#define STRAP_OPT 0x008
+#define GMI_AD0 (1 << 4)
+#define GMI_AD1 (1 << 5)
+#define RAM_ID_MASK (GMI_AD0 | GMI_AD1)
+#define RAM_CODE_SHIFT 4
+
static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
[TEGRA_REVISION_UNKNOWN] = "unknown",
[TEGRA_REVISION_A02] = "A02",
@@ -88,6 +99,9 @@ void tegra_init_fuse(void)
reg = tegra_fuse_readl(FUSE_SPARE_BIT);
tegra_core_process_id = (reg >> 12) & 3;
+ reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);
+ tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;
+
tegra_revision = tegra_get_revision();
pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
index e418d40..e0cc4bc 100644
--- a/arch/arm/mach-tegra/fuse.h
+++ b/arch/arm/mach-tegra/fuse.h
@@ -39,6 +39,8 @@ extern int tegra_cpu_process_id;
extern int tegra_core_process_id;
extern enum tegra_revision tegra_revision;
+extern int tegra_bct_strapping;
+
unsigned long long tegra_chip_uid(void);
void tegra_init_fuse(void);
--
1.7.8.GIT
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 6/9] arm/tegra: emc: convert tegra2_emc to a platform driver
[not found] ` <1324599468-12845-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
` (4 preceding siblings ...)
2011-12-23 0:17 ` [PATCH 5/9] arm/tegra: fuse: add bct strapping reading Olof Johansson
@ 2011-12-23 0:17 ` Olof Johansson
[not found] ` <1324599468-12845-7-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2011-12-23 0:17 ` [PATCH 7/9] arm/tegra: emc: device tree bindings Olof Johansson
` (2 subsequent siblings)
8 siblings, 1 reply; 45+ messages in thread
From: Olof Johansson @ 2011-12-23 0:17 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Olof Johansson
This is the first step in making it device-tree aware and get rid of the
in-kernel EMC tables (of which there are none in mainline, thankfully).
Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
---
arch/arm/mach-tegra/tegra2_emc.c | 110 ++++++++++++++++++++++++-------
arch/arm/mach-tegra/tegra2_emc.h | 11 +--
include/linux/platform_data/tegra_emc.h | 34 ++++++++++
3 files changed, 125 insertions(+), 30 deletions(-)
create mode 100644 include/linux/platform_data/tegra_emc.h
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
index 0f7ae6e..9ef61e8 100644
--- a/arch/arm/mach-tegra/tegra2_emc.c
+++ b/arch/arm/mach-tegra/tegra2_emc.c
@@ -20,6 +20,8 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/tegra_emc.h>
#include <mach/iomap.h>
@@ -32,18 +34,17 @@ static bool emc_enable;
#endif
module_param(emc_enable, bool, 0644);
-static void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE);
-static const struct tegra_emc_table *tegra_emc_table;
-static int tegra_emc_table_size;
+static struct platform_device *emc_pdev;
+static void __iomem *emc_regbase;
static inline void emc_writel(u32 val, unsigned long addr)
{
- writel(val, emc + addr);
+ writel(val, emc_regbase + addr);
}
static inline u32 emc_readl(unsigned long addr)
{
- return readl(emc + addr);
+ return readl(emc_regbase + addr);
}
static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
@@ -98,15 +99,15 @@ static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
/* Select the closest EMC rate that is higher than the requested rate */
long tegra_emc_round_rate(unsigned long rate)
{
+ struct tegra_emc_pdata *pdata;
int i;
int best = -1;
unsigned long distance = ULONG_MAX;
- if (!tegra_emc_table)
+ if (!emc_pdev)
return -EINVAL;
- if (!emc_enable)
- return -EINVAL;
+ pdata = emc_pdev->dev.platform_data;
pr_debug("%s: %lu\n", __func__, rate);
@@ -116,10 +117,10 @@ long tegra_emc_round_rate(unsigned long rate)
*/
rate = rate / 2 / 1000;
- for (i = 0; i < tegra_emc_table_size; i++) {
- if (tegra_emc_table[i].rate >= rate &&
- (tegra_emc_table[i].rate - rate) < distance) {
- distance = tegra_emc_table[i].rate - rate;
+ for (i = 0; i < pdata->num_tables; i++) {
+ if (pdata->tables[i].rate >= rate &&
+ (pdata->tables[i].rate - rate) < distance) {
+ distance = pdata->tables[i].rate - rate;
best = i;
}
}
@@ -127,9 +128,9 @@ long tegra_emc_round_rate(unsigned long rate)
if (best < 0)
return -EINVAL;
- pr_debug("%s: using %lu\n", __func__, tegra_emc_table[best].rate);
+ pr_debug("%s: using %lu\n", __func__, pdata->tables[best].rate);
- return tegra_emc_table[best].rate * 2 * 1000;
+ return pdata->tables[best].rate * 2 * 1000;
}
/*
@@ -142,37 +143,100 @@ long tegra_emc_round_rate(unsigned long rate)
*/
int tegra_emc_set_rate(unsigned long rate)
{
+ struct tegra_emc_pdata *pdata;
int i;
int j;
- if (!tegra_emc_table)
+ if (!emc_pdev)
return -EINVAL;
+ pdata = emc_pdev->dev.platform_data;
+
/*
* The EMC clock rate is twice the bus rate, and the bus rate is
* measured in kHz
*/
rate = rate / 2 / 1000;
- for (i = 0; i < tegra_emc_table_size; i++)
- if (tegra_emc_table[i].rate == rate)
+ for (i = 0; i < pdata->num_tables; i++)
+ if (pdata->tables[i].rate == rate)
break;
- if (i >= tegra_emc_table_size)
+ if (i >= pdata->num_tables)
return -EINVAL;
pr_debug("%s: setting to %lu\n", __func__, rate);
for (j = 0; j < TEGRA_EMC_NUM_REGS; j++)
- emc_writel(tegra_emc_table[i].regs[j], emc_reg_addr[j]);
+ emc_writel(pdata->tables[i].regs[j], emc_reg_addr[j]);
- emc_readl(tegra_emc_table[i].regs[TEGRA_EMC_NUM_REGS - 1]);
+ emc_readl(pdata->tables[i].regs[TEGRA_EMC_NUM_REGS - 1]);
return 0;
}
-void tegra_init_emc(const struct tegra_emc_table *table, int table_size)
+static int __devinit tegra_emc_probe(struct platform_device *pdev)
+{
+ struct tegra_emc_pdata *pdata;
+ struct clk *c = clk_get_sys("emc", NULL);
+ struct clk *user;
+ struct resource *res;
+ unsigned long max = 0;
+ int i;
+
+ if (!emc_enable) {
+ dev_err(&pdev->dev, "disabled per module parameter\n");
+ return -ENODEV;
+ }
+
+ pdata = pdev->dev.platform_data;
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "missing platform data\n");
+ return -ENXIO;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "missing register base\n");
+ return -ENOMEM;
+ }
+
+ if (!request_mem_region(res->start, resource_size(res), "tegra_emc")) {
+ dev_err(&pdev->dev, "failed to request register region\n");
+ return -EBUSY;
+ }
+
+ emc_regbase = ioremap(res->start, resource_size(res));
+
+ /* Since default max_rate on emc clock is the same as firmware set
+ * it to before booting, raise it up here based on known timings.
+ */
+
+ for (i = 0; i < pdata->num_tables; i++)
+ if (pdata->tables[i].rate > max)
+ max = pdata->tables[i].rate;
+
+ c->max_rate = max * 2 * 1000;
+
+ list_for_each_entry(user, &c->shared_bus_list, u.shared_bus_user.node)
+ user->max_rate = c->max_rate;
+
+ emc_pdev = pdev;
+
+ return 0;
+}
+
+static struct platform_driver tegra_emc_driver = {
+ .driver = {
+ .name = "tegra-emc",
+ .owner = THIS_MODULE,
+ },
+ .probe = tegra_emc_probe,
+};
+
+static int __init tegra_emc_init(void)
{
- tegra_emc_table = table;
- tegra_emc_table_size = table_size;
+ return platform_driver_register(&tegra_emc_driver);
}
+device_initcall(tegra_emc_init);
diff --git a/arch/arm/mach-tegra/tegra2_emc.h b/arch/arm/mach-tegra/tegra2_emc.h
index 19f08cb..f61409b 100644
--- a/arch/arm/mach-tegra/tegra2_emc.h
+++ b/arch/arm/mach-tegra/tegra2_emc.h
@@ -15,13 +15,10 @@
*
*/
-#define TEGRA_EMC_NUM_REGS 46
-
-struct tegra_emc_table {
- unsigned long rate;
- u32 regs[TEGRA_EMC_NUM_REGS];
-};
+#ifndef __MACH_TEGRA_TEGRA2_EMC_H_
+#define __MACH_TEGRA_TEGRA2_EMC_H
int tegra_emc_set_rate(unsigned long rate);
long tegra_emc_round_rate(unsigned long rate);
-void tegra_init_emc(const struct tegra_emc_table *table, int table_size);
+
+#endif
diff --git a/include/linux/platform_data/tegra_emc.h b/include/linux/platform_data/tegra_emc.h
new file mode 100644
index 0000000..df67505
--- /dev/null
+++ b/include/linux/platform_data/tegra_emc.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>
+ * Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
+ *
+ * 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 __TEGRA_EMC_H_
+#define __TEGRA_EMC_H_
+
+#define TEGRA_EMC_NUM_REGS 46
+
+struct tegra_emc_table {
+ unsigned long rate;
+ u32 regs[TEGRA_EMC_NUM_REGS];
+};
+
+struct tegra_emc_pdata {
+ int num_tables;
+ struct tegra_emc_table *tables;
+};
+
+#endif
--
1.7.8.GIT
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 7/9] arm/tegra: emc: device tree bindings
[not found] ` <1324599468-12845-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
` (5 preceding siblings ...)
2011-12-23 0:17 ` [PATCH 6/9] arm/tegra: emc: convert tegra2_emc to a platform driver Olof Johansson
@ 2011-12-23 0:17 ` Olof Johansson
[not found] ` <1324599468-12845-8-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2011-12-23 0:17 ` [PATCH 8/9] arm/tegra: seaboard: add EMC table to device tree Olof Johansson
2011-12-23 0:17 ` [PATCH 9/9] arm/tegra: emc: device tree support Olof Johansson
8 siblings, 1 reply; 45+ messages in thread
From: Olof Johansson @ 2011-12-23 0:17 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Olof Johansson,
Rob Herring, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
Device tree bindings for the EMC tables on tegra.
Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
Cc: Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
---
.../devicetree/bindings/arm/tegra/emc.txt | 100 ++++++++++++++++++++
arch/arm/boot/dts/tegra20.dtsi | 7 ++
2 files changed, 107 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/tegra/emc.txt
diff --git a/Documentation/devicetree/bindings/arm/tegra/emc.txt b/Documentation/devicetree/bindings/arm/tegra/emc.txt
new file mode 100644
index 0000000..09335f8
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/tegra/emc.txt
@@ -0,0 +1,100 @@
+Embedded Memory Controller
+
+Properties:
+- name : Should be emc
+- #address-cells : Should be 1
+- #size-cells : Should be 0
+- compatible : Should contain "nvidia,tegra20-emc".
+- reg : Offset and length of the register set for the device
+- nvidia,use-ram-code : If present, the sub-nodes will be addressed
+ and chosen using the ramcode board selector. If omitted, only one
+ set of tables can be present and said tables will be used
+ irrespective of ram-code configuration.
+
+Child device nodes describe the memory settings for different configurations and clock rates.
+
+Example:
+
+ emc@7000f400 {
+ #address-cells = < 1 >;
+ #size-cells = < 0 >;
+ compatible = "nvidia,tegra20-emc";
+ reg = <0x7000f4000 0x200>;
+ }
+
+
+Embedded Memory Controller ram-code table
+
+If the emc node has the nvidia,use-ram-code property present, then the
+next level of nodes below the emc table are used to specify which settings
+apply for which ram-code settings.
+
+If the emc node lacks the nvidia,use-ram-code property, this level is omitted
+and the tables are stored directly under the emc node (see below).
+
+Properties:
+
+- name : Should be emc-tables
+- nvidia,ram-code : the binary representation of the ram-code board strappings
+ for which this node (and children) are valid.
+
+
+
+Embedded Memory Controller configuration table
+
+This is a table containing the EMC register settings for the various
+operating speeds of the memory controller. They are always located as
+subnodes of the emc controller node.
+
+There are two ways of specifying which tables to use:
+
+* The simplest is if there is just one set of tables in the device tree,
+ and they will always be used (based on which frequency is used).
+ This is the preferred method, especially when firmware can fill in
+ this information based on the specific system information and just
+ pass it on to the kernel.
+
+* The slightly more complex one is when more than one memory configuration
+ might exist on the system. The Tegra20 platform handles this during
+ early boot by selecting one out of possible 4 memory settings based
+ on a 2-pin "ram code" bootstrap setting on the board. The values of
+ these strappings can be read through a register in the SoC, and thus
+ used to select which tables to use.
+
+Properties:
+- name : Should be emc-table
+- compatible : Should contain "nvidia,tegra20-emc-table".
+- reg : either an opaque enumerator to tell different tables apart, or
+ the valid frequency for which the table should be used (in kHz).
+- clock-frequency : the clock frequency for the EMC at which this
+ table should be used (in kHz).
+- nvidia,emc-registers : a 46 word array of EMC registers to be programmed
+ for operation at the 'clock-frequency' setting.
+ The order and contents of the registers are:
+ RC, RFC, RAS, RP, R2W, W2R, R2P, W2P, RD_RCD, WR_RCD, RRD, REXT,
+ WDV, QUSE, QRST, QSAFE, RDV, REFRESH, BURST_REFRESH_NUM, PDEX2WR,
+ PDEX2RD, PCHG2PDEN, ACT2PDEN, AR2PDEN, RW2PDEN, TXSR, TCKE, TFAW,
+ TRPAB, TCLKSTABLE, TCLKSTOP, TREFBW, QUSE_EXTRA, FBIO_CFG6, ODT_WRITE,
+ ODT_READ, FBIO_CFG5, CFG_DIG_DLL, DLL_XFORM_DQS, DLL_XFORM_QUSE,
+ ZCAL_REF_CNT, ZCAL_WAIT_CNT, AUTO_CAL_INTERVAL, CFG_CLKTRIM_0,
+ CFG_CLKTRIM_1, CFG_CLKTRIM_2
+
+ emc-table@166000 {
+ reg = <166000>;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = < 166000 >;
+ nvidia,emc-registers = < 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 >;
+ };
+
+ emc-table@333000 {
+ reg = <333000>;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = < 333000 >;
+ nvidia,emc-registers = < 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 >;
+ };
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 3da7afd..c162241 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -120,6 +120,13 @@
interrupts = < 0 91 0x04 >;
};
+ emc@7000f400 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nvidia,tegra20-emc";
+ reg = <0x7000f400 0x200>;
+ };
+
sdhci@c8000000 {
compatible = "nvidia,tegra20-sdhci";
reg = <0xc8000000 0x200>;
--
1.7.8.GIT
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 8/9] arm/tegra: seaboard: add EMC table to device tree
[not found] ` <1324599468-12845-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
` (6 preceding siblings ...)
2011-12-23 0:17 ` [PATCH 7/9] arm/tegra: emc: device tree bindings Olof Johansson
@ 2011-12-23 0:17 ` Olof Johansson
[not found] ` <1324599468-12845-9-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2011-12-23 0:17 ` [PATCH 9/9] arm/tegra: emc: device tree support Olof Johansson
8 siblings, 1 reply; 45+ messages in thread
From: Olof Johansson @ 2011-12-23 0:17 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Olof Johansson
Timings for the T25 version of seaboard, only one memory manufacturer
and timing table (two speeds).
Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
---
arch/arm/boot/dts/tegra-seaboard.dts | 38 ++++++++++++++++++++++++++++++++++
1 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts
index b55a02e..7ccf67e 100644
--- a/arch/arm/boot/dts/tegra-seaboard.dts
+++ b/arch/arm/boot/dts/tegra-seaboard.dts
@@ -93,4 +93,42 @@
gpio-key,wakeup;
};
};
+
+ emc@7000f400 {
+ emc-table@190000 {
+ reg = < 190000 >;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = < 190000 >;
+ nvidia,emc-registers = < 0x0000000c 0x00000026
+ 0x00000009 0x00000003 0x00000004 0x00000004
+ 0x00000002 0x0000000c 0x00000003 0x00000003
+ 0x00000002 0x00000001 0x00000004 0x00000005
+ 0x00000004 0x00000009 0x0000000d 0x0000059f
+ 0x00000000 0x00000003 0x00000003 0x00000003
+ 0x00000003 0x00000001 0x0000000b 0x000000c8
+ 0x00000003 0x00000007 0x00000004 0x0000000f
+ 0x00000002 0x00000000 0x00000000 0x00000002
+ 0x00000000 0x00000000 0x00000083 0xa06204ae
+ 0x007dc010 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000 >;
+ };
+
+ emc-table@380000 {
+ reg = < 380000 >;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = < 380000 >;
+ nvidia,emc-registers = < 0x00000017 0x0000004b
+ 0x00000012 0x00000006 0x00000004 0x00000005
+ 0x00000003 0x0000000c 0x00000006 0x00000006
+ 0x00000003 0x00000001 0x00000004 0x00000005
+ 0x00000004 0x00000009 0x0000000d 0x00000b5f
+ 0x00000000 0x00000003 0x00000003 0x00000006
+ 0x00000006 0x00000001 0x00000011 0x000000c8
+ 0x00000003 0x0000000e 0x00000007 0x0000000f
+ 0x00000002 0x00000000 0x00000000 0x00000002
+ 0x00000000 0x00000000 0x00000083 0xe044048b
+ 0x007d8010 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000 >;
+ };
+ };
};
--
1.7.8.GIT
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH 9/9] arm/tegra: emc: device tree support
[not found] ` <1324599468-12845-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
` (7 preceding siblings ...)
2011-12-23 0:17 ` [PATCH 8/9] arm/tegra: seaboard: add EMC table to device tree Olof Johansson
@ 2011-12-23 0:17 ` Olof Johansson
[not found] ` <1324599468-12845-10-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
8 siblings, 1 reply; 45+ messages in thread
From: Olof Johansson @ 2011-12-23 0:17 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Olof Johansson
Add device tree support to the emc driver, filling in the platform data
based on the DT bindings.
Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
---
arch/arm/mach-tegra/apbio.c | 2 +-
arch/arm/mach-tegra/tegra2_emc.c | 154 ++++++++++++++++++++++++++++++++-----
2 files changed, 134 insertions(+), 22 deletions(-)
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
index 7af9a4e..ee0ea89 100644
--- a/arch/arm/mach-tegra/apbio.c
+++ b/arch/arm/mach-tegra/apbio.c
@@ -64,7 +64,7 @@ out:
out_fail:
mutex_unlock(&tegra_apb_dma_lock);
- return true;
+ return false;
}
static void apb_dma_complete(struct tegra_dma_req *req)
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
index 9ef61e8..34749fa 100644
--- a/arch/arm/mach-tegra/tegra2_emc.c
+++ b/arch/arm/mach-tegra/tegra2_emc.c
@@ -20,12 +20,14 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/platform_data/tegra_emc.h>
#include <mach/iomap.h>
#include "tegra2_emc.h"
+#include "fuse.h"
#ifdef CONFIG_TEGRA_EMC_SCALING_ENABLE
static bool emc_enable = true;
@@ -175,27 +177,135 @@ int tegra_emc_set_rate(unsigned long rate)
return 0;
}
+#ifdef CONFIG_OF
+static struct device_node *tegra_emc_ramcode_devnode(struct device_node *np)
+{
+ struct device_node *iter;
+ u32 reg;
+
+ for_each_child_of_node(np, iter) {
+ if (!of_property_read_u32(np, "nvidia,ram-code", ®))
+ continue;
+ if (reg == tegra_bct_strapping)
+ return of_node_get(iter);
+ }
+
+ return NULL;
+}
+
+static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
+ struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *tnp, *iter;
+ struct tegra_emc_pdata *pdata;
+ int ret, i, num_tables;
+
+ if (!np)
+ return NULL;
+
+ if (of_find_property(np, "nvidia,use-ram-code", NULL)) {
+ tnp = tegra_emc_ramcode_devnode(np);
+ if (!tnp)
+ dev_warn(&pdev->dev,
+ "can't find emc table for ram-code 0x%02x\n",
+ tegra_bct_strapping);
+ } else
+ tnp = of_node_get(np);
+
+ if (!tnp)
+ return NULL;
+
+ num_tables = 0;
+ for_each_child_of_node(tnp, iter)
+ if (of_device_is_compatible(iter, "nvidia,tegra20-emc-table"))
+ num_tables++;
+
+ if (!num_tables) {
+ pdata = NULL;
+ goto out;
+ }
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ pdata->tables = devm_kzalloc(&pdev->dev,
+ sizeof(struct tegra_emc_table) * num_tables,
+ GFP_KERNEL);
+
+ i = 0;
+ for_each_child_of_node(tnp, iter) {
+ u32 prop;
+
+ ret = of_property_read_u32(iter, "clock-frequency", &prop);
+ if (ret) {
+ dev_err(&pdev->dev, "no clock-frequency in %s\n",
+ iter->full_name);
+ continue;
+ }
+ pdata->tables[i].rate = prop;
+
+ ret = of_property_read_u32_array(iter, "nvidia,emc-registers",
+ pdata->tables[i].regs,
+ TEGRA_EMC_NUM_REGS);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "malformed emc-registers property in %s\n",
+ iter->full_name);
+ continue;
+ }
+
+ i++;
+ }
+ pdata->num_tables = i;
+
+out:
+ of_node_put(tnp);
+ return pdata;
+}
+#else
+static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
+ struct platform_device *pdev)
+{
+ return NULL;
+}
+#endif
+
+static struct tegra_emc_pdata __devinit *tegra_emc_fill_pdata(struct platform_device *pdev)
+{
+ struct clk *c = clk_get_sys(NULL, "emc");
+ struct tegra_emc_pdata *pdata;
+ int i;
+
+ WARN_ON(pdev->dev.platform_data);
+ BUG_ON(IS_ERR_OR_NULL(c));
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ pdata->tables = devm_kzalloc(&pdev->dev,
+ sizeof(struct tegra_emc_table),
+ GFP_KERNEL);
+
+ pdata->tables[0].rate = clk_get_rate(c);
+
+ for (i = 0; i < TEGRA_EMC_NUM_REGS; i++)
+ pdata->tables[0].regs[i] = emc_readl(emc_reg_addr[i]);
+
+ pdata->num_tables = 1;
+
+ dev_info(&pdev->dev, "no tables provided, using settings for %ld kHz\n",
+ pdata->tables[0].rate / 2000);
+
+ return pdata;
+}
+
static int __devinit tegra_emc_probe(struct platform_device *pdev)
{
struct tegra_emc_pdata *pdata;
- struct clk *c = clk_get_sys("emc", NULL);
- struct clk *user;
struct resource *res;
- unsigned long max = 0;
- int i;
if (!emc_enable) {
dev_err(&pdev->dev, "disabled per module parameter\n");
return -ENODEV;
}
- pdata = pdev->dev.platform_data;
-
- if (!pdata) {
- dev_err(&pdev->dev, "missing platform data\n");
- return -ENXIO;
- }
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "missing register base\n");
@@ -209,28 +319,30 @@ static int __devinit tegra_emc_probe(struct platform_device *pdev)
emc_regbase = ioremap(res->start, resource_size(res));
- /* Since default max_rate on emc clock is the same as firmware set
- * it to before booting, raise it up here based on known timings.
- */
-
- for (i = 0; i < pdata->num_tables; i++)
- if (pdata->tables[i].rate > max)
- max = pdata->tables[i].rate;
+ pdata = pdev->dev.platform_data;
- c->max_rate = max * 2 * 1000;
+ if (!pdata)
+ pdata = tegra_emc_dt_parse_pdata(pdev);
- list_for_each_entry(user, &c->shared_bus_list, u.shared_bus_user.node)
- user->max_rate = c->max_rate;
+ if (!pdata)
+ pdata = tegra_emc_fill_pdata(pdev);
+ pdev->dev.platform_data = pdata;
emc_pdev = pdev;
return 0;
}
+static struct of_device_id tegra_emc_of_match[] __devinitdata = {
+ { .compatible = "nvidia,tegra20-emc", },
+ { },
+};
+
static struct platform_driver tegra_emc_driver = {
.driver = {
.name = "tegra-emc",
.owner = THIS_MODULE,
+ .of_match_table = tegra_emc_of_match,
},
.probe = tegra_emc_probe,
};
--
1.7.8.GIT
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH 4/9] arm/tegra: fuse: add functions to access chip revision
2011-12-23 0:17 ` [PATCH 4/9] arm/tegra: fuse: add functions to access chip revision Olof Johansson
@ 2011-12-23 10:47 ` Henning Heinold
[not found] ` <20111223104751.GA22157-RGm7CqJPa6S97g7+dlk11ZJjESxClBkh@public.gmane.org>
[not found] ` <1324599468-12845-5-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
1 sibling, 1 reply; 45+ messages in thread
From: Henning Heinold @ 2011-12-23 10:47 UTC (permalink / raw)
To: Olof Johansson; +Cc: linux-tegra, swarren, linux-arm-kernel, ccross
On Thu, Dec 22, 2011 at 04:17:43PM -0800, Olof Johansson wrote:
> Add function to get chip revision, and print it out at boot time.
>
> Restructure the fuse access to just use cached variables instead
> of always reading the fuses, and export those variables directly
> instead of using accessor functions.
>
> Add a SKU ID table of currently known values.
>
> Based on code originally by Colin Cross <ccross@android.com>.
>
> Signed-off-by: Olof Johansson <olof@lixom.net>
> ---
> arch/arm/mach-tegra/fuse.c | 80 +++++++++++++++++++++++------------
> arch/arm/mach-tegra/fuse.h | 31 +++++++++++--
> arch/arm/mach-tegra/tegra2_clocks.c | 2 +-
> 3 files changed, 80 insertions(+), 33 deletions(-)
>
> diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
> index daf3f57..2ddede9 100644
> --- a/arch/arm/mach-tegra/fuse.c
> +++ b/arch/arm/mach-tegra/fuse.c
> @@ -30,20 +30,70 @@
> #define FUSE_SKU_INFO 0x110
> #define FUSE_SPARE_BIT 0x200
>
> +int tegra_sku_id;
> +int tegra_cpu_process_id;
> +int tegra_core_process_id;
> +enum tegra_revision tegra_revision;
> +
> +static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
> + [TEGRA_REVISION_UNKNOWN] = "unknown",
> + [TEGRA_REVISION_A02] = "A02",
> + [TEGRA_REVISION_A03] = "A03",
> + [TEGRA_REVISION_A03p] = "A03 prime",
> + [TEGRA_REVISION_A04] = "A04",
> +};
> +
Hi Olof,
can you please add here [TEGRA_REVISION_A01] = "A01", too. It is used in the nvidia git tree and affects the new beta xorg
driver.
Bye Henning
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 7/9] arm/tegra: emc: device tree bindings
[not found] ` <1324599468-12845-8-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
@ 2012-01-02 9:00 ` Grant Likely
2012-01-06 0:01 ` Stephen Warren
2012-01-12 21:48 ` Simon Glass
2 siblings, 0 replies; 45+ messages in thread
From: Grant Likely @ 2012-01-02 9:00 UTC (permalink / raw)
To: Olof Johansson
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
On Thu, Dec 22, 2011 at 04:17:46PM -0800, Olof Johansson wrote:
> Device tree bindings for the EMC tables on tegra.
>
> Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
> Cc: Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Okay by me.
Acked-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
> ---
> .../devicetree/bindings/arm/tegra/emc.txt | 100 ++++++++++++++++++++
> arch/arm/boot/dts/tegra20.dtsi | 7 ++
> 2 files changed, 107 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/arm/tegra/emc.txt
>
> diff --git a/Documentation/devicetree/bindings/arm/tegra/emc.txt b/Documentation/devicetree/bindings/arm/tegra/emc.txt
> new file mode 100644
> index 0000000..09335f8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/tegra/emc.txt
> @@ -0,0 +1,100 @@
> +Embedded Memory Controller
> +
> +Properties:
> +- name : Should be emc
> +- #address-cells : Should be 1
> +- #size-cells : Should be 0
> +- compatible : Should contain "nvidia,tegra20-emc".
> +- reg : Offset and length of the register set for the device
> +- nvidia,use-ram-code : If present, the sub-nodes will be addressed
> + and chosen using the ramcode board selector. If omitted, only one
> + set of tables can be present and said tables will be used
> + irrespective of ram-code configuration.
> +
> +Child device nodes describe the memory settings for different configurations and clock rates.
> +
> +Example:
> +
> + emc@7000f400 {
> + #address-cells = < 1 >;
> + #size-cells = < 0 >;
> + compatible = "nvidia,tegra20-emc";
> + reg = <0x7000f4000 0x200>;
> + }
> +
> +
> +Embedded Memory Controller ram-code table
> +
> +If the emc node has the nvidia,use-ram-code property present, then the
> +next level of nodes below the emc table are used to specify which settings
> +apply for which ram-code settings.
> +
> +If the emc node lacks the nvidia,use-ram-code property, this level is omitted
> +and the tables are stored directly under the emc node (see below).
> +
> +Properties:
> +
> +- name : Should be emc-tables
> +- nvidia,ram-code : the binary representation of the ram-code board strappings
> + for which this node (and children) are valid.
> +
> +
> +
> +Embedded Memory Controller configuration table
> +
> +This is a table containing the EMC register settings for the various
> +operating speeds of the memory controller. They are always located as
> +subnodes of the emc controller node.
> +
> +There are two ways of specifying which tables to use:
> +
> +* The simplest is if there is just one set of tables in the device tree,
> + and they will always be used (based on which frequency is used).
> + This is the preferred method, especially when firmware can fill in
> + this information based on the specific system information and just
> + pass it on to the kernel.
> +
> +* The slightly more complex one is when more than one memory configuration
> + might exist on the system. The Tegra20 platform handles this during
> + early boot by selecting one out of possible 4 memory settings based
> + on a 2-pin "ram code" bootstrap setting on the board. The values of
> + these strappings can be read through a register in the SoC, and thus
> + used to select which tables to use.
> +
> +Properties:
> +- name : Should be emc-table
> +- compatible : Should contain "nvidia,tegra20-emc-table".
> +- reg : either an opaque enumerator to tell different tables apart, or
> + the valid frequency for which the table should be used (in kHz).
> +- clock-frequency : the clock frequency for the EMC at which this
> + table should be used (in kHz).
> +- nvidia,emc-registers : a 46 word array of EMC registers to be programmed
> + for operation at the 'clock-frequency' setting.
> + The order and contents of the registers are:
> + RC, RFC, RAS, RP, R2W, W2R, R2P, W2P, RD_RCD, WR_RCD, RRD, REXT,
> + WDV, QUSE, QRST, QSAFE, RDV, REFRESH, BURST_REFRESH_NUM, PDEX2WR,
> + PDEX2RD, PCHG2PDEN, ACT2PDEN, AR2PDEN, RW2PDEN, TXSR, TCKE, TFAW,
> + TRPAB, TCLKSTABLE, TCLKSTOP, TREFBW, QUSE_EXTRA, FBIO_CFG6, ODT_WRITE,
> + ODT_READ, FBIO_CFG5, CFG_DIG_DLL, DLL_XFORM_DQS, DLL_XFORM_QUSE,
> + ZCAL_REF_CNT, ZCAL_WAIT_CNT, AUTO_CAL_INTERVAL, CFG_CLKTRIM_0,
> + CFG_CLKTRIM_1, CFG_CLKTRIM_2
> +
> + emc-table@166000 {
> + reg = <166000>;
> + compatible = "nvidia,tegra20-emc-table";
> + clock-frequency = < 166000 >;
> + nvidia,emc-registers = < 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> + 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> + 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> + 0 0 0 0 >;
> + };
> +
> + emc-table@333000 {
> + reg = <333000>;
> + compatible = "nvidia,tegra20-emc-table";
> + clock-frequency = < 333000 >;
> + nvidia,emc-registers = < 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> + 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> + 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> + 0 0 0 0 >;
> + };
> diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
> index 3da7afd..c162241 100644
> --- a/arch/arm/boot/dts/tegra20.dtsi
> +++ b/arch/arm/boot/dts/tegra20.dtsi
> @@ -120,6 +120,13 @@
> interrupts = < 0 91 0x04 >;
> };
>
> + emc@7000f400 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + compatible = "nvidia,tegra20-emc";
> + reg = <0x7000f400 0x200>;
> + };
> +
> sdhci@c8000000 {
> compatible = "nvidia,tegra20-sdhci";
> reg = <0xc8000000 0x200>;
> --
> 1.7.8.GIT
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 4/9] arm/tegra: fuse: add functions to access chip revision
[not found] ` <20111223104751.GA22157-RGm7CqJPa6S97g7+dlk11ZJjESxClBkh@public.gmane.org>
@ 2012-01-04 3:46 ` Olof Johansson
0 siblings, 0 replies; 45+ messages in thread
From: Olof Johansson @ 2012-01-04 3:46 UTC (permalink / raw)
To: Henning Heinold
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Hi,
On Fri, Dec 23, 2011 at 2:47 AM, Henning Heinold
<heinold-cPcqOTmdTlv31zTM6d8ziw@public.gmane.org> wrote:
> On Thu, Dec 22, 2011 at 04:17:43PM -0800, Olof Johansson wrote:
>> +static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
>> + [TEGRA_REVISION_UNKNOWN] = "unknown",
>> + [TEGRA_REVISION_A02] = "A02",
>> + [TEGRA_REVISION_A03] = "A03",
>> + [TEGRA_REVISION_A03p] = "A03 prime",
>> + [TEGRA_REVISION_A04] = "A04",
>> +};
>> +
>
> Hi Olof,
>
> can you please add here [TEGRA_REVISION_A01] = "A01", too. It is used in the nvidia git tree and affects the new beta xorg
> driver.
How does it affect the xorg driver? Do you have hardware that is based
on A01? I wouldn't expect there to be any products out there with it
-- A01 has a handful of errata that is not handled in mainline, etc.
-Olof
^ permalink raw reply [flat|nested] 45+ messages in thread
* RE: [PATCH 2/9] arm/tegra: use APB DMA for accessing APB devices
[not found] ` <1324599468-12845-3-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
@ 2012-01-04 22:08 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F14F6-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-05 5:49 ` [PATCH v2] " Olof Johansson
1 sibling, 1 reply; 45+ messages in thread
From: Stephen Warren @ 2012-01-04 22:08 UTC (permalink / raw)
To: Olof Johansson,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
> Tegra2 hangs if APB registers are accessed from the cpu during an
> apb dma operation. The workaround is to use apb dma to read/write the
> registers instead.
...
> diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
...
> +bool tegra_apb_init(void)
> +{
...
> +out:
> + mutex_unlock(&tegra_apb_dma_lock);
> + return true;
> +
> +out_fail:
> + mutex_unlock(&tegra_apb_dma_lock);
> + return true;
Presumably that should be "return false".
> +u32 tegra_apb_readl(unsigned long offset)
> +{
> + struct tegra_dma_req req;
> + int ret;
> +
> + if (!tegra_apb_dma && !tegra_apb_init())
> + return readl(IO_TO_VIRT(offset));
> +
> + mutex_lock(&tegra_apb_dma_lock);
> + req.complete = apb_dma_complete;
> + req.to_memory = 1;
> + req.dest_addr = tegra_apb_bb_phys;
> + req.dest_bus_width = 32;
> + req.dest_wrap = 1;
> + req.source_addr = offset;
> + req.source_bus_width = 32;
> + req.source_wrap = 4;
> + req.req_sel = 0;
Should that be TEGRA_DMA_REQ_SEL_CNTR instead of 0? Although I'm not
sure what "CNTR" means, and the documentation doesn't seem to say.
> + req.size = 4;
> +
> + INIT_COMPLETION(tegra_apb_wait);
> +
> + tegra_dma_enqueue_req(tegra_apb_dma, &req);
> +
> + ret = wait_for_completion_timeout(&tegra_apb_wait,
> + msecs_to_jiffies(50));
> +
> + if (WARN(ret == 0, "apb read dma timed out"))
> + *(u32 *)tegra_apb_bb = 0;
On failure, you should probably call tegra_dma_dequeue_req() to cancel
the DMA request, otherwise (a) it'll wake up and trash some future
transfer, or (b) it'll be in the queue forever, and prevent any future
DMA requests from being programmed into HW.
Those two comments repeated from tegra_apb_writel().
--
nvpublic
^ permalink raw reply [flat|nested] 45+ messages in thread
* RE: [PATCH 4/9] arm/tegra: fuse: add functions to access chip revision
[not found] ` <1324599468-12845-5-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
@ 2012-01-04 23:20 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F156A-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-05 5:50 ` [PATCH v2] " Olof Johansson
1 sibling, 1 reply; 45+ messages in thread
From: Stephen Warren @ 2012-01-04 23:20 UTC (permalink / raw)
To: Olof Johansson,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
> Add function to get chip revision, and print it out at boot time.
>
> Restructure the fuse access to just use cached variables instead
> of always reading the fuses, and export those variables directly
> instead of using accessor functions.
>
> Add a SKU ID table of currently known values.
> +static enum tegra_revision tegra_get_revision(void)
> +{
> + void __iomem *chip_id = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804;
> + u32 id = readl(chip_id);
> +
> + switch ((id >> 16) & 0xf) {
We probably should decode A01 too; I certainly had a Tegra30 A01 until
recently, so it's entirely possible others do and want a meaningful
result.
Should the "A" should be decoded from the register too? It's bits 7:4
of the register and IIRC, 0=??? 1=A, presumably 2=B etc.
> + case 2:
> + return TEGRA_REVISION_A02;
> + case 3:
> + if (get_spare_fuse(18) || get_spare_fuse(19))
> + return TEGRA_REVISION_A03p;
Does that apply equally to Tegra30 as well as Tegra20? I'm afraid I don't
know, but if you need I can try and find out.
> + else
> + return TEGRA_REVISION_A03;
> + case 4:
> + return TEGRA_REVISION_A04;
And there's space in the register for numbers higher than 4, although I
don't think there's any current silicon where this would matter.
> + default:
> + return TEGRA_REVISION_UNKNOWN;
> + }
> +}
--
nvpublic
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 4/9] arm/tegra: fuse: add functions to access chip revision
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F156A-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
@ 2012-01-04 23:36 ` Olof Johansson
0 siblings, 0 replies; 45+ messages in thread
From: Olof Johansson @ 2012-01-04 23:36 UTC (permalink / raw)
To: Stephen Warren
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
On Wed, Jan 4, 2012 at 3:20 PM, Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
>> Add function to get chip revision, and print it out at boot time.
>>
>> Restructure the fuse access to just use cached variables instead
>> of always reading the fuses, and export those variables directly
>> instead of using accessor functions.
>>
>> Add a SKU ID table of currently known values.
>
>> +static enum tegra_revision tegra_get_revision(void)
>> +{
>> + void __iomem *chip_id = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804;
>> + u32 id = readl(chip_id);
>> +
>> + switch ((id >> 16) & 0xf) {
>
> We probably should decode A01 too; I certainly had a Tegra30 A01 until
> recently, so it's entirely possible others do and want a meaningful
> result.
Ah yes, T30. I was thinking of T20/25 A01. I'll add it.
> Should the "A" should be decoded from the register too? It's bits 7:4
> of the register and IIRC, 0=??? 1=A, presumably 2=B etc.
Well, only A is documented in my TRM. :-) I think it's safe to keep
it UNKNOWN until known.
>> + case 2:
>> + return TEGRA_REVISION_A02;
>> + case 3:
>> + if (get_spare_fuse(18) || get_spare_fuse(19))
>> + return TEGRA_REVISION_A03p;
>
> Does that apply equally to Tegra30 as well as Tegra20? I'm afraid I don't
> know, but if you need I can try and find out.
I doubt it, so it needs to be conditional. Will add.
>> + else
>> + return TEGRA_REVISION_A03;
>> + case 4:
>> + return TEGRA_REVISION_A04;
>
> And there's space in the register for numbers higher than 4, although I
> don't think there's any current silicon where this would matter.
Same here, not necessarily need to allocate all that much more than
what's known to be needed.
-Olof
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 2/9] arm/tegra: use APB DMA for accessing APB devices
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F14F6-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
@ 2012-01-04 23:39 ` Olof Johansson
0 siblings, 0 replies; 45+ messages in thread
From: Olof Johansson @ 2012-01-04 23:39 UTC (permalink / raw)
To: Stephen Warren
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
On Wed, Jan 4, 2012 at 2:08 PM, Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
>> Tegra2 hangs if APB registers are accessed from the cpu during an
>> apb dma operation. The workaround is to use apb dma to read/write the
>> registers instead.
> ...
>> diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
> ...
>> +bool tegra_apb_init(void)
>> +{
> ...
>> +out:
>> + mutex_unlock(&tegra_apb_dma_lock);
>> + return true;
>> +
>> +out_fail:
>> + mutex_unlock(&tegra_apb_dma_lock);
>> + return true;
>
> Presumably that should be "return false".
Yes, my bad. There's an accidental chunk in a later patch that swaps
it back to false that got squashed with the wrong patch.
>
>> +u32 tegra_apb_readl(unsigned long offset)
>> +{
>> + struct tegra_dma_req req;
>> + int ret;
>> +
>> + if (!tegra_apb_dma && !tegra_apb_init())
>> + return readl(IO_TO_VIRT(offset));
>> +
>> + mutex_lock(&tegra_apb_dma_lock);
>> + req.complete = apb_dma_complete;
>> + req.to_memory = 1;
>> + req.dest_addr = tegra_apb_bb_phys;
>> + req.dest_bus_width = 32;
>> + req.dest_wrap = 1;
>> + req.source_addr = offset;
>> + req.source_bus_width = 32;
>> + req.source_wrap = 4;
>> + req.req_sel = 0;
>
> Should that be TEGRA_DMA_REQ_SEL_CNTR instead of 0? Although I'm not
> sure what "CNTR" means, and the documentation doesn't seem to say.
Sure, will update.
>> + req.size = 4;
>> +
>> + INIT_COMPLETION(tegra_apb_wait);
>> +
>> + tegra_dma_enqueue_req(tegra_apb_dma, &req);
>> +
>> + ret = wait_for_completion_timeout(&tegra_apb_wait,
>> + msecs_to_jiffies(50));
>> +
>> + if (WARN(ret == 0, "apb read dma timed out"))
>> + *(u32 *)tegra_apb_bb = 0;
>
> On failure, you should probably call tegra_dma_dequeue_req() to cancel
> the DMA request, otherwise (a) it'll wake up and trash some future
> transfer, or (b) it'll be in the queue forever, and prevent any future
> DMA requests from being programmed into HW.
>
> Those two comments repeated from tegra_apb_writel().
Good point, will update.
-Olof
^ permalink raw reply [flat|nested] 45+ messages in thread
* RE: [PATCH 6/9] arm/tegra: emc: convert tegra2_emc to a platform driver
[not found] ` <1324599468-12845-7-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
@ 2012-01-04 23:39 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F158A-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-05 5:56 ` [PATCH v2] " Olof Johansson
1 sibling, 1 reply; 45+ messages in thread
From: Stephen Warren @ 2012-01-04 23:39 UTC (permalink / raw)
To: Olof Johansson,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
> This is the first step in making it device-tree aware and get rid of the
> in-kernel EMC tables (of which there are none in mainline, thankfully).
> -void tegra_init_emc(const struct tegra_emc_table *table, int table_size)
> +static int __devinit tegra_emc_probe(struct platform_device *pdev)
> +{
...
> + }
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!res) {
> + dev_err(&pdev->dev, "missing register base\n");
> + return -ENOMEM;
> + }
> +
> + if (!request_mem_region(res->start, resource_size(res), "tegra_emc")) {
Something is wrong with the indentation there.
> + /* Since default max_rate on emc clock is the same as firmware set
> + * it to before booting, raise it up here based on known timings.
> + */
> +
> + for (i = 0; i < pdata->num_tables; i++)
> + if (pdata->tables[i].rate > max)
> + max = pdata->tables[i].rate;
> +
> + c->max_rate = max * 2 * 1000;
> +
> + list_for_each_entry(user, &c->shared_bus_list, u.shared_bus_user.node)
> + user->max_rate = c->max_rate;
Hmm. I guess that works OK for now. Using some kind of accessor might
be nice; I'm not sure how that could be implemented once there's a
common clock framework, and this code can't touch the clock internals.
--
nvpublic
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 6/9] arm/tegra: emc: convert tegra2_emc to a platform driver
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F158A-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
@ 2012-01-04 23:42 ` Olof Johansson
0 siblings, 0 replies; 45+ messages in thread
From: Olof Johansson @ 2012-01-04 23:42 UTC (permalink / raw)
To: Stephen Warren
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
On Wed, Jan 4, 2012 at 3:39 PM, Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
>> This is the first step in making it device-tree aware and get rid of the
>> in-kernel EMC tables (of which there are none in mainline, thankfully).
>
>> -void tegra_init_emc(const struct tegra_emc_table *table, int table_size)
>> +static int __devinit tegra_emc_probe(struct platform_device *pdev)
>> +{
> ...
>> + }
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + if (!res) {
>> + dev_err(&pdev->dev, "missing register base\n");
>> + return -ENOMEM;
>> + }
>> +
>> + if (!request_mem_region(res->start, resource_size(res), "tegra_emc")) {
>
> Something is wrong with the indentation there.
>
>> + /* Since default max_rate on emc clock is the same as firmware set
>> + * it to before booting, raise it up here based on known timings.
>> + */
>> +
>> + for (i = 0; i < pdata->num_tables; i++)
>> + if (pdata->tables[i].rate > max)
>> + max = pdata->tables[i].rate;
>> +
>> + c->max_rate = max * 2 * 1000;
>> +
>> + list_for_each_entry(user, &c->shared_bus_list, u.shared_bus_user.node)
>> + user->max_rate = c->max_rate;
>
> Hmm. I guess that works OK for now. Using some kind of accessor might
> be nice; I'm not sure how that could be implemented once there's a
> common clock framework, and this code can't touch the clock internals.
Oh dear, that code should have been ripped out in the patch I posted.
It is definitely not to be left in there.
We're going to assume that firmware boots the system at maximum
performance so the above shouldn't be needed. I guess I could add a
warning for cases where different operation is detected.
-Olof
^ permalink raw reply [flat|nested] 45+ messages in thread
* RE: [PATCH 8/9] arm/tegra: seaboard: add EMC table to device tree
[not found] ` <1324599468-12845-9-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
@ 2012-01-04 23:51 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F1590-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
0 siblings, 1 reply; 45+ messages in thread
From: Stephen Warren @ 2012-01-04 23:51 UTC (permalink / raw)
To: Olof Johansson,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
> Timings for the T25 version of seaboard, only one memory manufacturer
> and timing table (two speeds).
There exist Seaboards with Tegra20 rather than Tegra25. Should we:
* Rename tegra-seaboard.dts to tegra-seaboard.dtsi
* Create tegra-seaboard-t20.dts and tegra-seaboard-t25.dts which include
tegra-seaboard.dtsi, and add the EMC tables to the Tegra25 version only?
Are the timings for true Seaboard and the Springbank variant identical?
--
nvpublic
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 8/9] arm/tegra: seaboard: add EMC table to device tree
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F1590-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
@ 2012-01-04 23:55 ` Olof Johansson
[not found] ` <CAOesGMhROzwyqMS89Nq0m6KRLNTbrkFrH9pUe6tfPR8gKTU+QA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 45+ messages in thread
From: Olof Johansson @ 2012-01-04 23:55 UTC (permalink / raw)
To: Stephen Warren
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
On Wed, Jan 4, 2012 at 3:51 PM, Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
>> Timings for the T25 version of seaboard, only one memory manufacturer
>> and timing table (two speeds).
>
> There exist Seaboards with Tegra20 rather than Tegra25. Should we:
> * Rename tegra-seaboard.dts to tegra-seaboard.dtsi
> * Create tegra-seaboard-t20.dts and tegra-seaboard-t25.dts which include
> tegra-seaboard.dtsi, and add the EMC tables to the Tegra25 version only?
Honestly, T20 seaboards are deprecated around here, we've been
replacing all we have with T25 models and keeping T20 support around
is a pain. I'd rather just ignore them if we can.
> Are the timings for true Seaboard and the Springbank variant identical?
I don't know, Springbank is a mostly nvidia-internal spin that I
haven't used much. I was of that impression though, since we have
never picked up any new specific support for it, it just runs with
seaboard code.
-Olof
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 8/9] arm/tegra: seaboard: add EMC table to device tree
[not found] ` <CAOesGMhROzwyqMS89Nq0m6KRLNTbrkFrH9pUe6tfPR8gKTU+QA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-01-05 0:11 ` Linus Walleij
[not found] ` <CACRpkdbtY+vOc-X8Ay1RyN61Xseepc2X-NnvFe=G++ASwrpOxQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 45+ messages in thread
From: Linus Walleij @ 2012-01-05 0:11 UTC (permalink / raw)
To: Olof Johansson
Cc: Stephen Warren,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org
On Thu, Jan 5, 2012 at 12:55 AM, Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org> wrote:
> On Wed, Jan 4, 2012 at 3:51 PM, Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
>> Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
>>> Timings for the T25 version of seaboard, only one memory manufacturer
>>> and timing table (two speeds).
>>
>> There exist Seaboards with Tegra20 rather than Tegra25. Should we:
>> * Rename tegra-seaboard.dts to tegra-seaboard.dtsi
>> * Create tegra-seaboard-t20.dts and tegra-seaboard-t25.dts which include
>> tegra-seaboard.dtsi, and add the EMC tables to the Tegra25 version only?
>
> Honestly, T20 seaboards are deprecated around here, we've been
> replacing all we have with T25 models and keeping T20 support around
> is a pain. I'd rather just ignore them if we can.
It's fun how board prototype problems sping up in several similar
companies :-)
When I am confronted with similar problems I have taken the stance:
Q: is the board available outside my company esp to community
people and other hackers who will be pissed if I screw it up?
If the answer is no, and there is no risk that anyone will blame you
for it on this mailinglist - delete it. Then handle the people that
yell at you internally and ask them to bring their board to the
junkpile.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 45+ messages in thread
* RE: [PATCH 9/9] arm/tegra: emc: device tree support
[not found] ` <1324599468-12845-10-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
@ 2012-01-05 0:27 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F15B3-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-05 6:02 ` [PATCH v2] " Olof Johansson
1 sibling, 1 reply; 45+ messages in thread
From: Stephen Warren @ 2012-01-05 0:27 UTC (permalink / raw)
To: Olof Johansson,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
> Add device tree support to the emc driver, filling in the platform data
> based on the DT bindings.
> diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
...
> out_fail:
> mutex_unlock(&tegra_apb_dma_lock);
> - return true;
> + return false;
There's the Easter egg;-)
> diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
> +#ifdef CONFIG_OF
> +static struct device_node *tegra_emc_ramcode_devnode(struct device_node *np)
> +{
> + struct device_node *iter;
> + u32 reg;
> +
> + for_each_child_of_node(np, iter) {
> + if (!of_property_read_u32(np, "nvidia,ram-code", ®))
> + continue;
I think that test is inverted; it returns 0 on success.
> +static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
> + struct platform_device *pdev)
...
> + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
> + pdata->tables = devm_kzalloc(&pdev->dev,
> + sizeof(struct tegra_emc_table) * num_tables,
> + GFP_KERNEL);
May as well use sizeof(*pdata->tables) there too for consistency?
> +
> + i = 0;
> + for_each_child_of_node(tnp, iter) {
> + u32 prop;
> +
> + ret = of_property_read_u32(iter, "clock-frequency", &prop);
> + if (ret) {
> + dev_err(&pdev->dev, "no clock-frequency in %s\n",
> + iter->full_name);
> + continue;
Not goto out?
> + }
> + pdata->tables[i].rate = prop;
> +
> + ret = of_property_read_u32_array(iter, "nvidia,emc-registers",
> + pdata->tables[i].regs,
> + TEGRA_EMC_NUM_REGS);
> + if (ret) {
> + dev_err(&pdev->dev,
> + "malformed emc-registers property in %s\n",
> + iter->full_name);
> + continue;
> + }
> +
> + i++;
> + }
> + pdata->num_tables = i;
Or here, "if (i != num_tables) error"?
> +
> +out:
> + of_node_put(tnp);
> + return pdata;
> +}
+static struct tegra_emc_pdata __devinit *tegra_emc_fill_pdata(struct platform_device *pdev)
+{
...
+ pdata->tables[0].rate = clk_get_rate(c);
...
+ dev_info(&pdev->dev, "no tables provided, using settings for %ld kHz\n",
+ pdata->tables[0].rate / 2000);
Is that right; I'm not sure if the /2 should be applied to what's stored
in .rate, or to the EMC clock value from clk_get_rate(). Similarly, is
the DT frequency the /2 version; there's no /2 in the DT parsing, but I
think I expect there to be.
--
nvpublic
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 9/9] arm/tegra: emc: device tree support
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F15B3-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
@ 2012-01-05 0:35 ` Olof Johansson
0 siblings, 0 replies; 45+ messages in thread
From: Olof Johansson @ 2012-01-05 0:35 UTC (permalink / raw)
To: Stephen Warren
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
On Wed, Jan 4, 2012 at 4:27 PM, Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
>> Add device tree support to the emc driver, filling in the platform data
>> based on the DT bindings.
>
>> diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
> ...
>> out_fail:
>> mutex_unlock(&tegra_apb_dma_lock);
>> - return true;
>> + return false;
>
> There's the Easter egg;-)
Yep, will move.
>
>> diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
>
>> +#ifdef CONFIG_OF
>> +static struct device_node *tegra_emc_ramcode_devnode(struct device_node *np)
>> +{
>> + struct device_node *iter;
>> + u32 reg;
>> +
>> + for_each_child_of_node(np, iter) {
>> + if (!of_property_read_u32(np, "nvidia,ram-code", ®))
>> + continue;
>
> I think that test is inverted; it returns 0 on success.
D'oh, thanks.
>
>> +static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
>> + struct platform_device *pdev)
> ...
>> + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
>> + pdata->tables = devm_kzalloc(&pdev->dev,
>> + sizeof(struct tegra_emc_table) * num_tables,
>> + GFP_KERNEL);
>
> May as well use sizeof(*pdata->tables) there too for consistency?
Sure, can change it.
>
>> +
>> + i = 0;
>> + for_each_child_of_node(tnp, iter) {
>> + u32 prop;
>> +
>> + ret = of_property_read_u32(iter, "clock-frequency", &prop);
>> + if (ret) {
>> + dev_err(&pdev->dev, "no clock-frequency in %s\n",
>> + iter->full_name);
>> + continue;
>
> Not goto out?
If there's ever another child-node added by someone (by mistake or
otherwise), this would start to fail. I'd rather try to survive it and
just not use the malformed entries.
>> + }
>> + pdata->tables[i].rate = prop;
>> +
>> + ret = of_property_read_u32_array(iter, "nvidia,emc-registers",
>> + pdata->tables[i].regs,
>> + TEGRA_EMC_NUM_REGS);
>> + if (ret) {
>> + dev_err(&pdev->dev,
>> + "malformed emc-registers property in %s\n",
>> + iter->full_name);
>> + continue;
>> + }
>> +
>> + i++;
>> + }
>> + pdata->num_tables = i;
>
> Or here, "if (i != num_tables) error"?
Same, I'd rather try to use what we got.
>> +
>> +out:
>> + of_node_put(tnp);
>> + return pdata;
>> +}
>
> +static struct tegra_emc_pdata __devinit *tegra_emc_fill_pdata(struct platform_device *pdev)
> +{
> ...
> + pdata->tables[0].rate = clk_get_rate(c);
> ...
> + dev_info(&pdev->dev, "no tables provided, using settings for %ld kHz\n",
> + pdata->tables[0].rate / 2000);
>
> Is that right; I'm not sure if the /2 should be applied to what's stored
> in .rate, or to the EMC clock value from clk_get_rate(). Similarly, is
> the DT frequency the /2 version; there's no /2 in the DT parsing, but I
> think I expect there to be.
The EMC clock is 2x the memory speed (on T20), so the above will print
out the actual speed of memory, not of the EMC block. The DT binding
is based on the EMC clock. I guess that could be considered
inconsistent, I can update the message to clarify.
-Olof
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 8/9] arm/tegra: seaboard: add EMC table to device tree
[not found] ` <CACRpkdbtY+vOc-X8Ay1RyN61Xseepc2X-NnvFe=G++ASwrpOxQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-01-05 5:43 ` Olof Johansson
0 siblings, 0 replies; 45+ messages in thread
From: Olof Johansson @ 2012-01-05 5:43 UTC (permalink / raw)
To: Linus Walleij
Cc: Stephen Warren,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org
On Thu, Jan 05, 2012 at 01:11:33AM +0100, Linus Walleij wrote:
> On Thu, Jan 5, 2012 at 12:55 AM, Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org> wrote:
> > On Wed, Jan 4, 2012 at 3:51 PM, Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> >> Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
> >>> Timings for the T25 version of seaboard, only one memory manufacturer
> >>> and timing table (two speeds).
> >>
> >> There exist Seaboards with Tegra20 rather than Tegra25. Should we:
> >> * Rename tegra-seaboard.dts to tegra-seaboard.dtsi
> >> * Create tegra-seaboard-t20.dts and tegra-seaboard-t25.dts which include
> >> tegra-seaboard.dtsi, and add the EMC tables to the Tegra25 version only?
> >
> > Honestly, T20 seaboards are deprecated around here, we've been
> > replacing all we have with T25 models and keeping T20 support around
> > is a pain. I'd rather just ignore them if we can.
>
> It's fun how board prototype problems sping up in several similar
> companies :-)
>
> When I am confronted with similar problems I have taken the stance:
>
> Q: is the board available outside my company esp to community
> people and other hackers who will be pissed if I screw it up?
>
> If the answer is no, and there is no risk that anyone will blame you
> for it on this mailinglist - delete it. Then handle the people that
> yell at you internally and ask them to bring their board to the
> junkpile.
Yeah, it's normally the way to do these things, with a transition
while the supply of newer hardware is still limited. It's a little more
complicated by the fact that I personally don't have control over what
Nvidia chooses to do internally. :)
-Olof
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v2] arm/tegra: use APB DMA for accessing APB devices
[not found] ` <1324599468-12845-3-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-04 22:08 ` Stephen Warren
@ 2012-01-05 5:49 ` Olof Johansson
[not found] ` <1325742554-32735-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
1 sibling, 1 reply; 45+ messages in thread
From: Olof Johansson @ 2012-01-05 5:49 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Olof Johansson
Tegra2 hangs if APB registers are accessed from the cpu during an
apb dma operation. The workaround is to use apb dma to read/write the
registers instead.
There is a dependency loop between fuses, clocks, and APBDMA. If dma
is enabled, fuse reads must go through APBDMA to avoid corruption due
to a hw bug. APBDMA requires a clock to be enabled. Clocks must read
a fuse to determine allowable cpu frequencies.
Separate out the fuse DMA initialization, and allow the fuse read
and write functions to be called without using DMA before the DMA
initialization has been completed. Access to the fuses before APBDMA
is initialized won't hit the hardware bug because nothing else can be
using DMA.
Original fuse registar access code from Varun Wadekar
<vwadekar-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>, improved by Colin Cross <ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>
and later moved to separate driver by Jon Mayo <jmayo-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>.
Major refactoring/cleanup by Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>.
Changes since v1:
* fix 'return false' on error condition
* use constant instead of 0 for req_sel
* dequeue dma ops in case of timeout
From: Jon Mayo <jmayo-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>.
Signed-off-by: Jon Mayo <jmayo-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>.
Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
---
arch/arm/mach-tegra/Makefile | 2 +-
arch/arm/mach-tegra/apbio.c | 145 ++++++++++++++++++++++++++++++++++++++++++
arch/arm/mach-tegra/apbio.h | 39 +++++++++++
arch/arm/mach-tegra/dma.c | 2 +
4 files changed, 187 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/mach-tegra/apbio.c
create mode 100644 arch/arm/mach-tegra/apbio.h
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index e120ff5..23d15fb 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pinmux-tegra30-tables.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o
obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
-obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o
+obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o apbio.o
obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
obj-$(CONFIG_TEGRA_PCI) += pcie.o
obj-$(CONFIG_USB_SUPPORT) += usb_phy.o
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
new file mode 100644
index 0000000..bec20cd
--- /dev/null
+++ b/arch/arm/mach-tegra/apbio.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2010 NVIDIA Corporation.
+ * 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/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include <linux/completion.h>
+#include <linux/sched.h>
+#include <linux/mutex.h>
+
+#include <mach/dma.h>
+#include <mach/iomap.h>
+
+#include "apbio.h"
+
+static DEFINE_MUTEX(tegra_apb_dma_lock);
+
+static struct tegra_dma_channel *tegra_apb_dma;
+static u32 *tegra_apb_bb;
+static dma_addr_t tegra_apb_bb_phys;
+static DECLARE_COMPLETION(tegra_apb_wait);
+
+bool tegra_apb_init(void)
+{
+ struct tegra_dma_channel *ch;
+
+ mutex_lock(&tegra_apb_dma_lock);
+
+ /* Check to see if we raced to setup */
+ if (tegra_apb_dma)
+ goto out;
+
+ ch = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT |
+ TEGRA_DMA_SHARED);
+
+ if (!ch)
+ goto out_fail;
+
+ tegra_apb_bb = dma_alloc_coherent(NULL, sizeof(u32),
+ &tegra_apb_bb_phys, GFP_KERNEL);
+ if (!tegra_apb_bb) {
+ pr_err("%s: can not allocate bounce buffer\n", __func__);
+ tegra_dma_free_channel(ch);
+ goto out_fail;
+ }
+
+ tegra_apb_dma = ch;
+out:
+ mutex_unlock(&tegra_apb_dma_lock);
+ return true;
+
+out_fail:
+ mutex_unlock(&tegra_apb_dma_lock);
+ return false;
+}
+
+static void apb_dma_complete(struct tegra_dma_req *req)
+{
+ complete(&tegra_apb_wait);
+}
+
+u32 tegra_apb_readl(unsigned long offset)
+{
+ struct tegra_dma_req req;
+ int ret;
+
+ if (!tegra_apb_dma && !tegra_apb_init())
+ return readl(IO_TO_VIRT(offset));
+
+ mutex_lock(&tegra_apb_dma_lock);
+ req.complete = apb_dma_complete;
+ req.to_memory = 1;
+ req.dest_addr = tegra_apb_bb_phys;
+ req.dest_bus_width = 32;
+ req.dest_wrap = 1;
+ req.source_addr = offset;
+ req.source_bus_width = 32;
+ req.source_wrap = 4;
+ req.req_sel = TEGRA_DMA_REQ_SEL_CNTR;
+ req.size = 4;
+
+ INIT_COMPLETION(tegra_apb_wait);
+
+ tegra_dma_enqueue_req(tegra_apb_dma, &req);
+
+ ret = wait_for_completion_timeout(&tegra_apb_wait,
+ msecs_to_jiffies(50));
+
+ if (WARN(ret == 0, "apb read dma timed out")) {
+ *(u32 *)tegra_apb_bb = 0;
+ tegra_dma_dequeue_req(tegra_apb_dma, &req);
+ }
+
+ mutex_unlock(&tegra_apb_dma_lock);
+ return *((u32 *)tegra_apb_bb);
+}
+
+void tegra_apb_writel(u32 value, unsigned long offset)
+{
+ struct tegra_dma_req req;
+ int ret;
+
+ if (!tegra_apb_dma && !tegra_apb_init()) {
+ writel(value, IO_TO_VIRT(offset));
+ return;
+ }
+
+ mutex_lock(&tegra_apb_dma_lock);
+ *((u32 *)tegra_apb_bb) = value;
+ req.complete = apb_dma_complete;
+ req.to_memory = 0;
+ req.dest_addr = offset;
+ req.dest_wrap = 4;
+ req.dest_bus_width = 32;
+ req.source_addr = tegra_apb_bb_phys;
+ req.source_bus_width = 32;
+ req.source_wrap = 1;
+ req.req_sel = TEGRA_DMA_REQ_SEL_CNTR;
+ req.size = 4;
+
+ INIT_COMPLETION(tegra_apb_wait);
+
+ tegra_dma_enqueue_req(tegra_apb_dma, &req);
+
+ ret = wait_for_completion_timeout(&tegra_apb_wait,
+ msecs_to_jiffies(50));
+
+ if (WARN(ret == 0, "apb write dma timed out"))
+ tegra_dma_dequeue_req(tegra_apb_dma, &req);
+
+ mutex_unlock(&tegra_apb_dma_lock);
+}
diff --git a/arch/arm/mach-tegra/apbio.h b/arch/arm/mach-tegra/apbio.h
new file mode 100644
index 0000000..8b49e8c
--- /dev/null
+++ b/arch/arm/mach-tegra/apbio.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 NVIDIA Corporation.
+ * 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_APBIO_H
+#define __MACH_TEGRA_APBIO_H
+
+#ifdef CONFIG_TEGRA_SYSTEM_DMA
+
+u32 tegra_apb_readl(unsigned long offset);
+void tegra_apb_writel(u32 value, unsigned long offset);
+
+#else
+#include <asm/io.h>
+#include <mach/io.h>
+
+static inline u32 tegra_apb_readl(unsigned long offset)
+{
+ return readl(IO_TO_VIRT(offset));
+}
+
+static inline void tegra_apb_writel(u32 value, unsigned long offset)
+{
+ writel(value, IO_TO_VIRT(offset));
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c
index 98b33c8..122e467 100644
--- a/arch/arm/mach-tegra/dma.c
+++ b/arch/arm/mach-tegra/dma.c
@@ -33,6 +33,8 @@
#include <mach/iomap.h>
#include <mach/suspend.h>
+#include "apbio.h"
+
#define APB_DMA_GEN 0x000
#define GEN_ENABLE (1<<31)
--
1.7.8.GIT
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v2] arm/tegra: fuse: add functions to access chip revision
[not found] ` <1324599468-12845-5-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-04 23:20 ` Stephen Warren
@ 2012-01-05 5:50 ` Olof Johansson
[not found] ` <1325742641-384-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
1 sibling, 1 reply; 45+ messages in thread
From: Olof Johansson @ 2012-01-05 5:50 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Olof Johansson
Add function to get chip revision, and print it out at boot time.
Restructure the fuse access to just use cached variables instead
of always reading the fuses, and export those variables directly
instead of using accessor functions.
Add a SKU ID table of currently known values.
Based on code originally by Colin Cross <ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>.
Changes since v1:
* Add A01 minor rev support
* Don't decode for A03p on anything but T2x
Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
---
arch/arm/mach-tegra/fuse.c | 85 ++++++++++++++++++++++++-----------
arch/arm/mach-tegra/fuse.h | 32 +++++++++++--
arch/arm/mach-tegra/tegra2_clocks.c | 2 +-
3 files changed, 86 insertions(+), 33 deletions(-)
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
index daf3f57..b1895c5 100644
--- a/arch/arm/mach-tegra/fuse.c
+++ b/arch/arm/mach-tegra/fuse.c
@@ -30,20 +30,75 @@
#define FUSE_SKU_INFO 0x110
#define FUSE_SPARE_BIT 0x200
+int tegra_sku_id;
+int tegra_cpu_process_id;
+int tegra_core_process_id;
+enum tegra_revision tegra_revision;
+
+static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
+ [TEGRA_REVISION_UNKNOWN] = "unknown",
+ [TEGRA_REVISION_A01] = "A01",
+ [TEGRA_REVISION_A02] = "A02",
+ [TEGRA_REVISION_A03] = "A03",
+ [TEGRA_REVISION_A03p] = "A03 prime",
+ [TEGRA_REVISION_A04] = "A04",
+};
+
static inline u32 tegra_fuse_readl(unsigned long offset)
{
return tegra_apb_readl(TEGRA_FUSE_BASE + offset);
}
+static inline bool get_spare_fuse(int bit)
+{
+ return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4);
+}
+
+static enum tegra_revision tegra_get_revision(void)
+{
+ void __iomem *chip_id = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804;
+ u32 id = readl(chip_id);
+ u32 minor_rev = (id >> 16) & 0xf;
+ u32 chipid = (id >> 8) & 0xff;
+
+ switch (minor_rev) {
+ case 1:
+ return TEGRA_REVISION_A01;
+ case 2:
+ return TEGRA_REVISION_A02;
+ case 3:
+ if (chipid == 0x20 && (get_spare_fuse(18) || get_spare_fuse(19)))
+ return TEGRA_REVISION_A03p;
+ else
+ return TEGRA_REVISION_A03;
+ case 4:
+ return TEGRA_REVISION_A04;
+ default:
+ return TEGRA_REVISION_UNKNOWN;
+ }
+}
+
void tegra_init_fuse(void)
{
u32 reg = readl(IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
reg |= 1 << 28;
writel(reg, IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
- pr_info("Tegra SKU: %d CPU Process: %d Core Process: %d\n",
- tegra_sku_id(), tegra_cpu_process_id(),
- tegra_core_process_id());
+ reg = tegra_fuse_readl(FUSE_SKU_INFO);
+ tegra_sku_id = reg & 0xFF;
+
+ reg = tegra_fuse_readl(FUSE_SPARE_BIT);
+ tegra_cpu_process_id = (reg >> 6) & 3;
+
+ reg = tegra_fuse_readl(FUSE_SPARE_BIT);
+ tegra_core_process_id = (reg >> 12) & 3;
+
+ tegra_revision = tegra_get_revision();
+
+ pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
+ tegra_revision_name[tegra_get_revision()],
+ tegra_sku_id, tegra_cpu_process_id,
+ tegra_core_process_id);
}
unsigned long long tegra_chip_uid(void)
@@ -54,27 +109,3 @@ unsigned long long tegra_chip_uid(void)
hi = tegra_fuse_readl(FUSE_UID_HIGH);
return (hi << 32ull) | lo;
}
-
-int tegra_sku_id(void)
-{
- int sku_id;
- u32 reg = tegra_fuse_readl(FUSE_SKU_INFO);
- sku_id = reg & 0xFF;
- return sku_id;
-}
-
-int tegra_cpu_process_id(void)
-{
- int cpu_process_id;
- u32 reg = tegra_fuse_readl(FUSE_SPARE_BIT);
- cpu_process_id = (reg >> 6) & 3;
- return cpu_process_id;
-}
-
-int tegra_core_process_id(void)
-{
- int core_process_id;
- u32 reg = tegra_fuse_readl(FUSE_SPARE_BIT);
- core_process_id = (reg >> 12) & 3;
- return core_process_id;
-}
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
index 584b2e2..7576aaf 100644
--- a/arch/arm/mach-tegra/fuse.h
+++ b/arch/arm/mach-tegra/fuse.h
@@ -1,6 +1,4 @@
/*
- * arch/arm/mach-tegra/fuse.c
- *
* Copyright (C) 2010 Google, Inc.
*
* Author:
@@ -17,8 +15,32 @@
*
*/
+#ifndef __MACH_TEGRA_FUSE_H
+#define __MACH_TEGRA_FUSE_H
+
+enum tegra_revision {
+ TEGRA_REVISION_UNKNOWN = 0,
+ TEGRA_REVISION_A01,
+ TEGRA_REVISION_A02,
+ TEGRA_REVISION_A03,
+ TEGRA_REVISION_A03p,
+ TEGRA_REVISION_A04,
+ TEGRA_REVISION_MAX,
+};
+
+#define SKU_ID_T20 8
+#define SKU_ID_T25SE 20
+#define SKU_ID_AP25 23
+#define SKU_ID_T25 24
+#define SKU_ID_AP25E 27
+#define SKU_ID_T25E 28
+
+extern int tegra_sku_id;
+extern int tegra_cpu_process_id;
+extern int tegra_core_process_id;
+extern enum tegra_revision tegra_revision;
+
unsigned long long tegra_chip_uid(void);
-int tegra_sku_id(void);
-int tegra_cpu_process_id(void);
-int tegra_core_process_id(void);
void tegra_init_fuse(void);
+
+#endif
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index ff9e6b6..74d314fd 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -720,7 +720,7 @@ static void tegra2_pllx_clk_init(struct clk *c)
{
tegra2_pll_clk_init(c);
- if (tegra_sku_id() == 7)
+ if (tegra_sku_id == 7)
c->max_rate = 750000000;
}
--
1.7.8.GIT
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v2] arm/tegra: emc: convert tegra2_emc to a platform driver
[not found] ` <1324599468-12845-7-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-04 23:39 ` Stephen Warren
@ 2012-01-05 5:56 ` Olof Johansson
[not found] ` <1325742994-1178-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
1 sibling, 1 reply; 45+ messages in thread
From: Olof Johansson @ 2012-01-05 5:56 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Olof Johansson
This is the first step in making it device-tree aware and get rid of the
in-kernel EMC tables (of which there are none in mainline, thankfully).
Changes since v1:
* Fixed messed up indentation
* Removed code that should be gone (was added here and removed later in series)
Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
---
arch/arm/mach-tegra/tegra2_emc.c | 96 +++++++++++++++++++++++-------
arch/arm/mach-tegra/tegra2_emc.h | 11 +--
include/linux/platform_data/tegra_emc.h | 34 +++++++++++
3 files changed, 111 insertions(+), 30 deletions(-)
create mode 100644 include/linux/platform_data/tegra_emc.h
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
index 0f7ae6e..604d6fc 100644
--- a/arch/arm/mach-tegra/tegra2_emc.c
+++ b/arch/arm/mach-tegra/tegra2_emc.c
@@ -20,6 +20,8 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/tegra_emc.h>
#include <mach/iomap.h>
@@ -32,18 +34,17 @@ static bool emc_enable;
#endif
module_param(emc_enable, bool, 0644);
-static void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE);
-static const struct tegra_emc_table *tegra_emc_table;
-static int tegra_emc_table_size;
+static struct platform_device *emc_pdev;
+static void __iomem *emc_regbase;
static inline void emc_writel(u32 val, unsigned long addr)
{
- writel(val, emc + addr);
+ writel(val, emc_regbase + addr);
}
static inline u32 emc_readl(unsigned long addr)
{
- return readl(emc + addr);
+ return readl(emc_regbase + addr);
}
static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
@@ -98,15 +99,15 @@ static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
/* Select the closest EMC rate that is higher than the requested rate */
long tegra_emc_round_rate(unsigned long rate)
{
+ struct tegra_emc_pdata *pdata;
int i;
int best = -1;
unsigned long distance = ULONG_MAX;
- if (!tegra_emc_table)
+ if (!emc_pdev)
return -EINVAL;
- if (!emc_enable)
- return -EINVAL;
+ pdata = emc_pdev->dev.platform_data;
pr_debug("%s: %lu\n", __func__, rate);
@@ -116,10 +117,10 @@ long tegra_emc_round_rate(unsigned long rate)
*/
rate = rate / 2 / 1000;
- for (i = 0; i < tegra_emc_table_size; i++) {
- if (tegra_emc_table[i].rate >= rate &&
- (tegra_emc_table[i].rate - rate) < distance) {
- distance = tegra_emc_table[i].rate - rate;
+ for (i = 0; i < pdata->num_tables; i++) {
+ if (pdata->tables[i].rate >= rate &&
+ (pdata->tables[i].rate - rate) < distance) {
+ distance = pdata->tables[i].rate - rate;
best = i;
}
}
@@ -127,9 +128,9 @@ long tegra_emc_round_rate(unsigned long rate)
if (best < 0)
return -EINVAL;
- pr_debug("%s: using %lu\n", __func__, tegra_emc_table[best].rate);
+ pr_debug("%s: using %lu\n", __func__, pdata->tables[best].rate);
- return tegra_emc_table[best].rate * 2 * 1000;
+ return pdata->tables[best].rate * 2 * 1000;
}
/*
@@ -142,37 +143,86 @@ long tegra_emc_round_rate(unsigned long rate)
*/
int tegra_emc_set_rate(unsigned long rate)
{
+ struct tegra_emc_pdata *pdata;
int i;
int j;
- if (!tegra_emc_table)
+ if (!emc_pdev)
return -EINVAL;
+ pdata = emc_pdev->dev.platform_data;
+
/*
* The EMC clock rate is twice the bus rate, and the bus rate is
* measured in kHz
*/
rate = rate / 2 / 1000;
- for (i = 0; i < tegra_emc_table_size; i++)
- if (tegra_emc_table[i].rate == rate)
+ for (i = 0; i < pdata->num_tables; i++)
+ if (pdata->tables[i].rate == rate)
break;
- if (i >= tegra_emc_table_size)
+ if (i >= pdata->num_tables)
return -EINVAL;
pr_debug("%s: setting to %lu\n", __func__, rate);
for (j = 0; j < TEGRA_EMC_NUM_REGS; j++)
- emc_writel(tegra_emc_table[i].regs[j], emc_reg_addr[j]);
+ emc_writel(pdata->tables[i].regs[j], emc_reg_addr[j]);
+
+ emc_readl(pdata->tables[i].regs[TEGRA_EMC_NUM_REGS - 1]);
+
+ return 0;
+}
+
+static int __devinit tegra_emc_probe(struct platform_device *pdev)
+{
+ struct tegra_emc_pdata *pdata;
+ struct clk *c = clk_get_sys("emc", NULL);
+ struct clk *user;
+ struct resource *res;
+ unsigned long max = 0;
+ int i;
+
+ if (!emc_enable) {
+ dev_err(&pdev->dev, "disabled per module parameter\n");
+ return -ENODEV;
+ }
+
+ pdata = pdev->dev.platform_data;
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "missing platform data\n");
+ return -ENXIO;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "missing register base\n");
+ return -ENOMEM;
+ }
+
+ if (!request_mem_region(res->start, resource_size(res), "tegra_emc")) {
+ dev_err(&pdev->dev, "failed to request register region\n");
+ return -EBUSY;
+ }
- emc_readl(tegra_emc_table[i].regs[TEGRA_EMC_NUM_REGS - 1]);
+ emc_regbase = ioremap(res->start, resource_size(res));
+ emc_pdev = pdev;
return 0;
}
-void tegra_init_emc(const struct tegra_emc_table *table, int table_size)
+static struct platform_driver tegra_emc_driver = {
+ .driver = {
+ .name = "tegra-emc",
+ .owner = THIS_MODULE,
+ },
+ .probe = tegra_emc_probe,
+};
+
+static int __init tegra_emc_init(void)
{
- tegra_emc_table = table;
- tegra_emc_table_size = table_size;
+ return platform_driver_register(&tegra_emc_driver);
}
+device_initcall(tegra_emc_init);
diff --git a/arch/arm/mach-tegra/tegra2_emc.h b/arch/arm/mach-tegra/tegra2_emc.h
index 19f08cb..f61409b 100644
--- a/arch/arm/mach-tegra/tegra2_emc.h
+++ b/arch/arm/mach-tegra/tegra2_emc.h
@@ -15,13 +15,10 @@
*
*/
-#define TEGRA_EMC_NUM_REGS 46
-
-struct tegra_emc_table {
- unsigned long rate;
- u32 regs[TEGRA_EMC_NUM_REGS];
-};
+#ifndef __MACH_TEGRA_TEGRA2_EMC_H_
+#define __MACH_TEGRA_TEGRA2_EMC_H
int tegra_emc_set_rate(unsigned long rate);
long tegra_emc_round_rate(unsigned long rate);
-void tegra_init_emc(const struct tegra_emc_table *table, int table_size);
+
+#endif
diff --git a/include/linux/platform_data/tegra_emc.h b/include/linux/platform_data/tegra_emc.h
new file mode 100644
index 0000000..df67505
--- /dev/null
+++ b/include/linux/platform_data/tegra_emc.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>
+ * Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
+ *
+ * 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 __TEGRA_EMC_H_
+#define __TEGRA_EMC_H_
+
+#define TEGRA_EMC_NUM_REGS 46
+
+struct tegra_emc_table {
+ unsigned long rate;
+ u32 regs[TEGRA_EMC_NUM_REGS];
+};
+
+struct tegra_emc_pdata {
+ int num_tables;
+ struct tegra_emc_table *tables;
+};
+
+#endif
--
1.7.8.GIT
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v3] arm/tegra: emc: convert tegra2_emc to a platform driver
[not found] ` <1325742994-1178-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
@ 2012-01-05 6:01 ` Olof Johansson
[not found] ` <1325743288-2460-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
0 siblings, 1 reply; 45+ messages in thread
From: Olof Johansson @ 2012-01-05 6:01 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Olof Johansson
This is the first step in making it device-tree aware and get rid of the
in-kernel EMC tables (of which there are none in mainline, thankfully).
Changes since v2:
* D'oh -- missed a couple of variables that were added, never used and then
later removed in a later patch.
Changes since v1:
* Fixed messed up indentation
* Removed code that should be gone (was added here and removed later in series)
Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
---
arch/arm/mach-tegra/tegra2_emc.c | 92 +++++++++++++++++++++++--------
arch/arm/mach-tegra/tegra2_emc.h | 11 +--
include/linux/platform_data/tegra_emc.h | 34 +++++++++++
3 files changed, 107 insertions(+), 30 deletions(-)
create mode 100644 include/linux/platform_data/tegra_emc.h
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
index 0f7ae6e..ad70180 100644
--- a/arch/arm/mach-tegra/tegra2_emc.c
+++ b/arch/arm/mach-tegra/tegra2_emc.c
@@ -20,6 +20,8 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/tegra_emc.h>
#include <mach/iomap.h>
@@ -32,18 +34,17 @@ static bool emc_enable;
#endif
module_param(emc_enable, bool, 0644);
-static void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE);
-static const struct tegra_emc_table *tegra_emc_table;
-static int tegra_emc_table_size;
+static struct platform_device *emc_pdev;
+static void __iomem *emc_regbase;
static inline void emc_writel(u32 val, unsigned long addr)
{
- writel(val, emc + addr);
+ writel(val, emc_regbase + addr);
}
static inline u32 emc_readl(unsigned long addr)
{
- return readl(emc + addr);
+ return readl(emc_regbase + addr);
}
static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
@@ -98,15 +99,15 @@ static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
/* Select the closest EMC rate that is higher than the requested rate */
long tegra_emc_round_rate(unsigned long rate)
{
+ struct tegra_emc_pdata *pdata;
int i;
int best = -1;
unsigned long distance = ULONG_MAX;
- if (!tegra_emc_table)
+ if (!emc_pdev)
return -EINVAL;
- if (!emc_enable)
- return -EINVAL;
+ pdata = emc_pdev->dev.platform_data;
pr_debug("%s: %lu\n", __func__, rate);
@@ -116,10 +117,10 @@ long tegra_emc_round_rate(unsigned long rate)
*/
rate = rate / 2 / 1000;
- for (i = 0; i < tegra_emc_table_size; i++) {
- if (tegra_emc_table[i].rate >= rate &&
- (tegra_emc_table[i].rate - rate) < distance) {
- distance = tegra_emc_table[i].rate - rate;
+ for (i = 0; i < pdata->num_tables; i++) {
+ if (pdata->tables[i].rate >= rate &&
+ (pdata->tables[i].rate - rate) < distance) {
+ distance = pdata->tables[i].rate - rate;
best = i;
}
}
@@ -127,9 +128,9 @@ long tegra_emc_round_rate(unsigned long rate)
if (best < 0)
return -EINVAL;
- pr_debug("%s: using %lu\n", __func__, tegra_emc_table[best].rate);
+ pr_debug("%s: using %lu\n", __func__, pdata->tables[best].rate);
- return tegra_emc_table[best].rate * 2 * 1000;
+ return pdata->tables[best].rate * 2 * 1000;
}
/*
@@ -142,37 +143,82 @@ long tegra_emc_round_rate(unsigned long rate)
*/
int tegra_emc_set_rate(unsigned long rate)
{
+ struct tegra_emc_pdata *pdata;
int i;
int j;
- if (!tegra_emc_table)
+ if (!emc_pdev)
return -EINVAL;
+ pdata = emc_pdev->dev.platform_data;
+
/*
* The EMC clock rate is twice the bus rate, and the bus rate is
* measured in kHz
*/
rate = rate / 2 / 1000;
- for (i = 0; i < tegra_emc_table_size; i++)
- if (tegra_emc_table[i].rate == rate)
+ for (i = 0; i < pdata->num_tables; i++)
+ if (pdata->tables[i].rate == rate)
break;
- if (i >= tegra_emc_table_size)
+ if (i >= pdata->num_tables)
return -EINVAL;
pr_debug("%s: setting to %lu\n", __func__, rate);
for (j = 0; j < TEGRA_EMC_NUM_REGS; j++)
- emc_writel(tegra_emc_table[i].regs[j], emc_reg_addr[j]);
+ emc_writel(pdata->tables[i].regs[j], emc_reg_addr[j]);
- emc_readl(tegra_emc_table[i].regs[TEGRA_EMC_NUM_REGS - 1]);
+ emc_readl(pdata->tables[i].regs[TEGRA_EMC_NUM_REGS - 1]);
return 0;
}
-void tegra_init_emc(const struct tegra_emc_table *table, int table_size)
+static int __devinit tegra_emc_probe(struct platform_device *pdev)
+{
+ struct tegra_emc_pdata *pdata;
+ struct resource *res;
+
+ if (!emc_enable) {
+ dev_err(&pdev->dev, "disabled per module parameter\n");
+ return -ENODEV;
+ }
+
+ pdata = pdev->dev.platform_data;
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "missing platform data\n");
+ return -ENXIO;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "missing register base\n");
+ return -ENOMEM;
+ }
+
+ if (!request_mem_region(res->start, resource_size(res), "tegra_emc")) {
+ dev_err(&pdev->dev, "failed to request register region\n");
+ return -EBUSY;
+ }
+
+ emc_regbase = ioremap(res->start, resource_size(res));
+ emc_pdev = pdev;
+
+ return 0;
+}
+
+static struct platform_driver tegra_emc_driver = {
+ .driver = {
+ .name = "tegra-emc",
+ .owner = THIS_MODULE,
+ },
+ .probe = tegra_emc_probe,
+};
+
+static int __init tegra_emc_init(void)
{
- tegra_emc_table = table;
- tegra_emc_table_size = table_size;
+ return platform_driver_register(&tegra_emc_driver);
}
+device_initcall(tegra_emc_init);
diff --git a/arch/arm/mach-tegra/tegra2_emc.h b/arch/arm/mach-tegra/tegra2_emc.h
index 19f08cb..f61409b 100644
--- a/arch/arm/mach-tegra/tegra2_emc.h
+++ b/arch/arm/mach-tegra/tegra2_emc.h
@@ -15,13 +15,10 @@
*
*/
-#define TEGRA_EMC_NUM_REGS 46
-
-struct tegra_emc_table {
- unsigned long rate;
- u32 regs[TEGRA_EMC_NUM_REGS];
-};
+#ifndef __MACH_TEGRA_TEGRA2_EMC_H_
+#define __MACH_TEGRA_TEGRA2_EMC_H
int tegra_emc_set_rate(unsigned long rate);
long tegra_emc_round_rate(unsigned long rate);
-void tegra_init_emc(const struct tegra_emc_table *table, int table_size);
+
+#endif
diff --git a/include/linux/platform_data/tegra_emc.h b/include/linux/platform_data/tegra_emc.h
new file mode 100644
index 0000000..df67505
--- /dev/null
+++ b/include/linux/platform_data/tegra_emc.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>
+ * Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
+ *
+ * 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 __TEGRA_EMC_H_
+#define __TEGRA_EMC_H_
+
+#define TEGRA_EMC_NUM_REGS 46
+
+struct tegra_emc_table {
+ unsigned long rate;
+ u32 regs[TEGRA_EMC_NUM_REGS];
+};
+
+struct tegra_emc_pdata {
+ int num_tables;
+ struct tegra_emc_table *tables;
+};
+
+#endif
--
1.7.8.GIT
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v2] arm/tegra: emc: device tree support
[not found] ` <1324599468-12845-10-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-05 0:27 ` Stephen Warren
@ 2012-01-05 6:02 ` Olof Johansson
[not found] ` <1325743338-2533-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
1 sibling, 1 reply; 45+ messages in thread
From: Olof Johansson @ 2012-01-05 6:02 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Olof Johansson
Add device tree support to the emc driver, filling in the platform data
based on the DT bindings.
Changes since v1:
* Unmangled some messed up patch squashes, moving changes to earlier patches
* Flipped an of_property_read_u32 return value test
* Clarified clock settings message on case where no table is provided
Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
---
arch/arm/mach-tegra/tegra2_emc.c | 146 ++++++++++++++++++++++++++++++++++++--
1 files changed, 139 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
index ad70180..0a40266 100644
--- a/arch/arm/mach-tegra/tegra2_emc.c
+++ b/arch/arm/mach-tegra/tegra2_emc.c
@@ -20,12 +20,14 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/platform_data/tegra_emc.h>
#include <mach/iomap.h>
#include "tegra2_emc.h"
+#include "fuse.h"
#ifdef CONFIG_TEGRA_EMC_SCALING_ENABLE
static bool emc_enable = true;
@@ -175,6 +177,127 @@ int tegra_emc_set_rate(unsigned long rate)
return 0;
}
+#ifdef CONFIG_OF
+static struct device_node *tegra_emc_ramcode_devnode(struct device_node *np)
+{
+ struct device_node *iter;
+ u32 reg;
+
+ for_each_child_of_node(np, iter) {
+ if (of_property_read_u32(np, "nvidia,ram-code", ®))
+ continue;
+ if (reg == tegra_bct_strapping)
+ return of_node_get(iter);
+ }
+
+ return NULL;
+}
+
+static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
+ struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *tnp, *iter;
+ struct tegra_emc_pdata *pdata;
+ int ret, i, num_tables;
+
+ if (!np)
+ return NULL;
+
+ if (of_find_property(np, "nvidia,use-ram-code", NULL)) {
+ tnp = tegra_emc_ramcode_devnode(np);
+ if (!tnp)
+ dev_warn(&pdev->dev,
+ "can't find emc table for ram-code 0x%02x\n",
+ tegra_bct_strapping);
+ } else
+ tnp = of_node_get(np);
+
+ if (!tnp)
+ return NULL;
+
+ num_tables = 0;
+ for_each_child_of_node(tnp, iter)
+ if (of_device_is_compatible(iter, "nvidia,tegra20-emc-table"))
+ num_tables++;
+
+ if (!num_tables) {
+ pdata = NULL;
+ goto out;
+ }
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ pdata->tables = devm_kzalloc(&pdev->dev,
+ sizeof(*pdata->tables) * num_tables,
+ GFP_KERNEL);
+
+ i = 0;
+ for_each_child_of_node(tnp, iter) {
+ u32 prop;
+
+ ret = of_property_read_u32(iter, "clock-frequency", &prop);
+ if (ret) {
+ dev_err(&pdev->dev, "no clock-frequency in %s\n",
+ iter->full_name);
+ continue;
+ }
+ pdata->tables[i].rate = prop;
+
+ ret = of_property_read_u32_array(iter, "nvidia,emc-registers",
+ pdata->tables[i].regs,
+ TEGRA_EMC_NUM_REGS);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "malformed emc-registers property in %s\n",
+ iter->full_name);
+ continue;
+ }
+
+ i++;
+ }
+ pdata->num_tables = i;
+
+out:
+ of_node_put(tnp);
+ return pdata;
+}
+#else
+static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
+ struct platform_device *pdev)
+{
+ return NULL;
+}
+#endif
+
+static struct tegra_emc_pdata __devinit *tegra_emc_fill_pdata(struct platform_device *pdev)
+{
+ struct clk *c = clk_get_sys(NULL, "emc");
+ struct tegra_emc_pdata *pdata;
+ unsigned long khz;
+ int i;
+
+ WARN_ON(pdev->dev.platform_data);
+ BUG_ON(IS_ERR_OR_NULL(c));
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ pdata->tables = devm_kzalloc(&pdev->dev,
+ sizeof(struct tegra_emc_table),
+ GFP_KERNEL);
+
+ pdata->tables[0].rate = clk_get_rate(c);
+
+ for (i = 0; i < TEGRA_EMC_NUM_REGS; i++)
+ pdata->tables[0].regs[i] = emc_readl(emc_reg_addr[i]);
+
+ pdata->num_tables = 1;
+
+ khz = pdata->tables[0].rate / 1000;
+ dev_info(&pdev->dev, "no tables provided, using %ld kHz emc, "
+ "%ld kHz mem\n", khz, khz/2);
+
+ return pdata;
+}
+
static int __devinit tegra_emc_probe(struct platform_device *pdev)
{
struct tegra_emc_pdata *pdata;
@@ -185,13 +308,6 @@ static int __devinit tegra_emc_probe(struct platform_device *pdev)
return -ENODEV;
}
- pdata = pdev->dev.platform_data;
-
- if (!pdata) {
- dev_err(&pdev->dev, "missing platform data\n");
- return -ENXIO;
- }
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "missing register base\n");
@@ -204,15 +320,31 @@ static int __devinit tegra_emc_probe(struct platform_device *pdev)
}
emc_regbase = ioremap(res->start, resource_size(res));
+
+ pdata = pdev->dev.platform_data;
+
+ if (!pdata)
+ pdata = tegra_emc_dt_parse_pdata(pdev);
+
+ if (!pdata)
+ pdata = tegra_emc_fill_pdata(pdev);
+
+ pdev->dev.platform_data = pdata;
emc_pdev = pdev;
return 0;
}
+static struct of_device_id tegra_emc_of_match[] __devinitdata = {
+ { .compatible = "nvidia,tegra20-emc", },
+ { },
+};
+
static struct platform_driver tegra_emc_driver = {
.driver = {
.name = "tegra-emc",
.owner = THIS_MODULE,
+ .of_match_table = tegra_emc_of_match,
},
.probe = tegra_emc_probe,
};
--
1.7.8.GIT
^ permalink raw reply related [flat|nested] 45+ messages in thread
* RE: [PATCH v2] arm/tegra: use APB DMA for accessing APB devices
[not found] ` <1325742554-32735-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
@ 2012-01-05 22:07 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F1812-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
0 siblings, 1 reply; 45+ messages in thread
From: Stephen Warren @ 2012-01-05 22:07 UTC (permalink / raw)
To: Olof Johansson,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Olof Johansson wrote at Wednesday, January 04, 2012 10:49 PM:
> Tegra2 hangs if APB registers are accessed from the cpu during an
> apb dma operation. The workaround is to use apb dma to read/write the
> registers instead.
...
> diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
...
> +u32 tegra_apb_readl(unsigned long offset)
...
> + INIT_COMPLETION(tegra_apb_wait);
> +
> + tegra_dma_enqueue_req(tegra_apb_dma, &req);
> +
> + ret = wait_for_completion_timeout(&tegra_apb_wait,
> + msecs_to_jiffies(50));
> +
> + if (WARN(ret == 0, "apb read dma timed out")) {
> + *(u32 *)tegra_apb_bb = 0;
> + tegra_dma_dequeue_req(tegra_apb_dma, &req);
I think you need to swap those last two lines to make absolutely sure
that the timeout handling doesn't race with an actual DMA completion.
Otherwise,
Acked-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
--
nvpublic
^ permalink raw reply [flat|nested] 45+ messages in thread
* RE: [PATCH v2] arm/tegra: fuse: add functions to access chip revision
[not found] ` <1325742641-384-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
@ 2012-01-05 22:08 ` Stephen Warren
0 siblings, 0 replies; 45+ messages in thread
From: Stephen Warren @ 2012-01-05 22:08 UTC (permalink / raw)
To: Olof Johansson,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Olof Johansson wrote at Wednesday, January 04, 2012 10:51 PM:
> Add function to get chip revision, and print it out at boot time.
>
> Restructure the fuse access to just use cached variables instead
> of always reading the fuses, and export those variables directly
> instead of using accessor functions.
>
> Add a SKU ID table of currently known values.
>
> Based on code originally by Colin Cross <ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>.
>
> Changes since v1:
>
> * Add A01 minor rev support
> * Don't decode for A03p on anything but T2x
>
> Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
Acked-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
--
nvpublic
^ permalink raw reply [flat|nested] 45+ messages in thread
* RE: [PATCH v3] arm/tegra: emc: convert tegra2_emc to a platform driver
[not found] ` <1325743288-2460-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
@ 2012-01-05 22:14 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F1818-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-06 1:42 ` [PATCH v4] ARM: tegra: " Olof Johansson
1 sibling, 1 reply; 45+ messages in thread
From: Stephen Warren @ 2012-01-05 22:14 UTC (permalink / raw)
To: Olof Johansson,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Olof Johansson wrote at Wednesday, January 04, 2012 11:01 PM:
> This is the first step in making it device-tree aware and get rid of the
> in-kernel EMC tables (of which there are none in mainline, thankfully).
>
> Changes since v2:
>
> * D'oh -- missed a couple of variables that were added, never used and then
> later removed in a later patch.
>
> Changes since v1:
>
> * Fixed messed up indentation
> * Removed code that should be gone (was added here and removed later in series)
>
> Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
...
> diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
...
> +static int __devinit tegra_emc_probe(struct platform_device *pdev)
...
> + if (!request_mem_region(res->start, resource_size(res), "tegra_emc")) {
> + dev_err(&pdev->dev, "failed to request register region\n");
> + return -EBUSY;
> + }
> +
> + emc_regbase = ioremap(res->start, resource_size(res));
Don't you need to error-check the ioremap() result, and undo the
request_mem_region() too? Or, use the devm variant to request the
region. The rest of the code checks emc_pdev!=NULL which won't detect
this failure.
Isn't there a get_resource && request && remap function now; I think I
recall a patch that wraps all that into one function, but it might have
been DT-only.
Otherwise,
Acked-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
--
nvpublic
^ permalink raw reply [flat|nested] 45+ messages in thread
* RE: [PATCH v2] arm/tegra: emc: device tree support
[not found] ` <1325743338-2533-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
@ 2012-01-05 22:35 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F182F-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
0 siblings, 1 reply; 45+ messages in thread
From: Stephen Warren @ 2012-01-05 22:35 UTC (permalink / raw)
To: Olof Johansson,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Olof Johansson wrote at Wednesday, January 04, 2012 11:02 PM:
> Add device tree support to the emc driver, filling in the platform data
> based on the DT bindings.
>
> Changes since v1:
>
> * Unmangled some messed up patch squashes, moving changes to earlier patches
> * Flipped an of_property_read_u32 return value test
> * Clarified clock settings message on case where no table is provided
>
> Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
...
> diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
...
> +static struct tegra_emc_pdata __devinit *tegra_emc_fill_pdata(struct platform_device *pdev)
...
> + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
> + pdata->tables = devm_kzalloc(&pdev->dev,
> + sizeof(struct tegra_emc_table),
> + GFP_KERNEL);
You could convert that one to sizeof(*pdata->tables) too, although feel
free to ignore this picky comment, or fix it up when you apply the change.
Otherwise,
Acked-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
--
nvpublic
^ permalink raw reply [flat|nested] 45+ messages in thread
* RE: [PATCH 7/9] arm/tegra: emc: device tree bindings
[not found] ` <1324599468-12845-8-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-02 9:00 ` Grant Likely
@ 2012-01-06 0:01 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F18A6-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-12 21:48 ` Simon Glass
2 siblings, 1 reply; 45+ messages in thread
From: Stephen Warren @ 2012-01-06 0:01 UTC (permalink / raw)
To: Olof Johansson,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
Rob Herring,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
> Device tree bindings for the EMC tables on tegra.
...
> diff --git a/Documentation/devicetree/bindings/arm/tegra/emc.txt
...
> +Embedded Memory Controller ram-code table
...
> +- name : Should be emc-tables
> +- nvidia,ram-code : the binary representation of the ram-code board strappings
> + for which this node (and children) are valid.
...
> +Embedded Memory Controller configuration table
...
> +- name : Should be emc-table
> +- compatible : Should contain "nvidia,tegra20-emc-table".
> +- reg : either an opaque enumerator to tell different tables apart, or
...
One more thought:
For consistency, should the "emc-tables" node also require a compatible
value? I suppose the existence of an "nvidia,ram-code" property is quite
likely to be indication enough that the node is compatible, but I wonder
if we shouldn't require and check an explicit compatible value at this
level too?
--
nvpublic
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 7/9] arm/tegra: emc: device tree bindings
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F18A6-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
@ 2012-01-06 1:20 ` Olof Johansson
[not found] ` <CAOesGMjeVm_PcsBnxfKX9Oe96QUaCsJrvuESCRZq5vwq9gD5xA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 45+ messages in thread
From: Olof Johansson @ 2012-01-06 1:20 UTC (permalink / raw)
To: Stephen Warren
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
Rob Herring,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
On Thu, Jan 5, 2012 at 4:01 PM, Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
>> Device tree bindings for the EMC tables on tegra.
> ...
>> diff --git a/Documentation/devicetree/bindings/arm/tegra/emc.txt
> ...
>> +Embedded Memory Controller ram-code table
> ...
>> +- name : Should be emc-tables
>> +- nvidia,ram-code : the binary representation of the ram-code board strappings
>> + for which this node (and children) are valid.
> ...
>> +Embedded Memory Controller configuration table
> ...
>> +- name : Should be emc-table
>> +- compatible : Should contain "nvidia,tegra20-emc-table".
>> +- reg : either an opaque enumerator to tell different tables apart, or
> ...
>
> One more thought:
>
> For consistency, should the "emc-tables" node also require a compatible
> value? I suppose the existence of an "nvidia,ram-code" property is quite
> likely to be indication enough that the node is compatible, but I wonder
> if we shouldn't require and check an explicit compatible value at this
> level too?
I can add it, it's trivial to add another check in
tegra_emc_ramcode_devnode, but I don't think there's much need to
bother. As long as nothing else is added that uses nvidia,ram-code as
a property we'll be OK, and we can control that.
-Olof
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v2] arm/tegra: use APB DMA for accessing APB devices
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F1812-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
@ 2012-01-06 1:22 ` Olof Johansson
0 siblings, 0 replies; 45+ messages in thread
From: Olof Johansson @ 2012-01-06 1:22 UTC (permalink / raw)
To: Stephen Warren
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
On Thu, Jan 5, 2012 at 2:07 PM, Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> Olof Johansson wrote at Wednesday, January 04, 2012 10:49 PM:
>> Tegra2 hangs if APB registers are accessed from the cpu during an
>> apb dma operation. The workaround is to use apb dma to read/write the
>> registers instead.
> ...
>> diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
> ...
>> +u32 tegra_apb_readl(unsigned long offset)
> ...
>> + INIT_COMPLETION(tegra_apb_wait);
>> +
>> + tegra_dma_enqueue_req(tegra_apb_dma, &req);
>> +
>> + ret = wait_for_completion_timeout(&tegra_apb_wait,
>> + msecs_to_jiffies(50));
>> +
>> + if (WARN(ret == 0, "apb read dma timed out")) {
>> + *(u32 *)tegra_apb_bb = 0;
>> + tegra_dma_dequeue_req(tegra_apb_dma, &req);
>
> I think you need to swap those last two lines to make absolutely sure
> that the timeout handling doesn't race with an actual DMA completion.
Ah, of course. Fixing that without reposting.
> Acked-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Thanks!
-Olof
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v2] arm/tegra: emc: device tree support
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F182F-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
@ 2012-01-06 1:26 ` Olof Johansson
0 siblings, 0 replies; 45+ messages in thread
From: Olof Johansson @ 2012-01-06 1:26 UTC (permalink / raw)
To: Stephen Warren
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
On Thu, Jan 5, 2012 at 2:35 PM, Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> Olof Johansson wrote at Wednesday, January 04, 2012 11:02 PM:
>> Add device tree support to the emc driver, filling in the platform data
>> based on the DT bindings.
>>
>> Changes since v1:
>>
>> * Unmangled some messed up patch squashes, moving changes to earlier patches
>> * Flipped an of_property_read_u32 return value test
>> * Clarified clock settings message on case where no table is provided
>>
>> Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
> ...
>> diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
> ...
>> +static struct tegra_emc_pdata __devinit *tegra_emc_fill_pdata(struct platform_device *pdev)
> ...
>> + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
>> + pdata->tables = devm_kzalloc(&pdev->dev,
>> + sizeof(struct tegra_emc_table),
>> + GFP_KERNEL);
>
> You could convert that one to sizeof(*pdata->tables) too, although feel
> free to ignore this picky comment, or fix it up when you apply the change.
>
> Otherwise,
>
> Acked-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Done, thanks.
-Olof
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v3] arm/tegra: emc: convert tegra2_emc to a platform driver
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F1818-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
@ 2012-01-06 1:36 ` Olof Johansson
0 siblings, 0 replies; 45+ messages in thread
From: Olof Johansson @ 2012-01-06 1:36 UTC (permalink / raw)
To: Stephen Warren
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
On Thu, Jan 5, 2012 at 2:14 PM, Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> Olof Johansson wrote at Wednesday, January 04, 2012 11:01 PM:
>> This is the first step in making it device-tree aware and get rid of the
>> in-kernel EMC tables (of which there are none in mainline, thankfully).
>>
>> Changes since v2:
>>
>> * D'oh -- missed a couple of variables that were added, never used and then
>> later removed in a later patch.
>>
>> Changes since v1:
>>
>> * Fixed messed up indentation
>> * Removed code that should be gone (was added here and removed later in series)
>>
>> Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
> ...
>> diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
> ...
>> +static int __devinit tegra_emc_probe(struct platform_device *pdev)
> ...
>> + if (!request_mem_region(res->start, resource_size(res), "tegra_emc")) {
>> + dev_err(&pdev->dev, "failed to request register region\n");
>> + return -EBUSY;
>> + }
>> +
>> + emc_regbase = ioremap(res->start, resource_size(res));
>
> Don't you need to error-check the ioremap() result, and undo the
> request_mem_region() too? Or, use the devm variant to request the
> region. The rest of the code checks emc_pdev!=NULL which won't detect
> this failure.
>
> Isn't there a get_resource && request && remap function now; I think I
> recall a patch that wraps all that into one function, but it might have
> been DT-only.
Nope, it's there -- devm_request_and_ioremap(). I'll move it over to
that and repost, it's a good idea.
-Olof
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v4] ARM: tegra: emc: convert tegra2_emc to a platform driver
[not found] ` <1325743288-2460-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-05 22:14 ` Stephen Warren
@ 2012-01-06 1:42 ` Olof Johansson
[not found] ` <1325814163-23980-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
1 sibling, 1 reply; 45+ messages in thread
From: Olof Johansson @ 2012-01-06 1:42 UTC (permalink / raw)
To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: swarren-DDmLM1+adcrQT0dZR+AlfA, ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Olof Johansson
This is the first step in making it device-tree aware and get rid of the
in-kernel EMC tables (of which there are none in mainline, thankfully).
Changes since v3:
* moved to devm_request_and_ioremap() in probe()
*
Changes since v2:
* D'oh -- missed a couple of variables that were added, never used and then
later removed in a later patch.
Changes since v1:
* Fixed messed up indentation
* Removed code that should be gone (was added here and removed later in series)
Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
---
arch/arm/mach-tegra/tegra2_emc.c | 92 +++++++++++++++++++++++--------
arch/arm/mach-tegra/tegra2_emc.h | 11 +--
include/linux/platform_data/tegra_emc.h | 34 +++++++++++
3 files changed, 107 insertions(+), 30 deletions(-)
create mode 100644 include/linux/platform_data/tegra_emc.h
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
index 0f7ae6e..e6229bb 100644
--- a/arch/arm/mach-tegra/tegra2_emc.c
+++ b/arch/arm/mach-tegra/tegra2_emc.c
@@ -16,10 +16,13 @@
*/
#include <linux/kernel.h>
+#include <linux/device.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/tegra_emc.h>
#include <mach/iomap.h>
@@ -32,18 +35,17 @@ static bool emc_enable;
#endif
module_param(emc_enable, bool, 0644);
-static void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE);
-static const struct tegra_emc_table *tegra_emc_table;
-static int tegra_emc_table_size;
+static struct platform_device *emc_pdev;
+static void __iomem *emc_regbase;
static inline void emc_writel(u32 val, unsigned long addr)
{
- writel(val, emc + addr);
+ writel(val, emc_regbase + addr);
}
static inline u32 emc_readl(unsigned long addr)
{
- return readl(emc + addr);
+ return readl(emc_regbase + addr);
}
static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
@@ -98,15 +100,15 @@ static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
/* Select the closest EMC rate that is higher than the requested rate */
long tegra_emc_round_rate(unsigned long rate)
{
+ struct tegra_emc_pdata *pdata;
int i;
int best = -1;
unsigned long distance = ULONG_MAX;
- if (!tegra_emc_table)
+ if (!emc_pdev)
return -EINVAL;
- if (!emc_enable)
- return -EINVAL;
+ pdata = emc_pdev->dev.platform_data;
pr_debug("%s: %lu\n", __func__, rate);
@@ -116,10 +118,10 @@ long tegra_emc_round_rate(unsigned long rate)
*/
rate = rate / 2 / 1000;
- for (i = 0; i < tegra_emc_table_size; i++) {
- if (tegra_emc_table[i].rate >= rate &&
- (tegra_emc_table[i].rate - rate) < distance) {
- distance = tegra_emc_table[i].rate - rate;
+ for (i = 0; i < pdata->num_tables; i++) {
+ if (pdata->tables[i].rate >= rate &&
+ (pdata->tables[i].rate - rate) < distance) {
+ distance = pdata->tables[i].rate - rate;
best = i;
}
}
@@ -127,9 +129,9 @@ long tegra_emc_round_rate(unsigned long rate)
if (best < 0)
return -EINVAL;
- pr_debug("%s: using %lu\n", __func__, tegra_emc_table[best].rate);
+ pr_debug("%s: using %lu\n", __func__, pdata->tables[best].rate);
- return tegra_emc_table[best].rate * 2 * 1000;
+ return pdata->tables[best].rate * 2 * 1000;
}
/*
@@ -142,37 +144,81 @@ long tegra_emc_round_rate(unsigned long rate)
*/
int tegra_emc_set_rate(unsigned long rate)
{
+ struct tegra_emc_pdata *pdata;
int i;
int j;
- if (!tegra_emc_table)
+ if (!emc_pdev)
return -EINVAL;
+ pdata = emc_pdev->dev.platform_data;
+
/*
* The EMC clock rate is twice the bus rate, and the bus rate is
* measured in kHz
*/
rate = rate / 2 / 1000;
- for (i = 0; i < tegra_emc_table_size; i++)
- if (tegra_emc_table[i].rate == rate)
+ for (i = 0; i < pdata->num_tables; i++)
+ if (pdata->tables[i].rate == rate)
break;
- if (i >= tegra_emc_table_size)
+ if (i >= pdata->num_tables)
return -EINVAL;
pr_debug("%s: setting to %lu\n", __func__, rate);
for (j = 0; j < TEGRA_EMC_NUM_REGS; j++)
- emc_writel(tegra_emc_table[i].regs[j], emc_reg_addr[j]);
+ emc_writel(pdata->tables[i].regs[j], emc_reg_addr[j]);
+
+ emc_readl(pdata->tables[i].regs[TEGRA_EMC_NUM_REGS - 1]);
+
+ return 0;
+}
+
+static int __devinit tegra_emc_probe(struct platform_device *pdev)
+{
+ struct tegra_emc_pdata *pdata;
+ struct resource *res;
+
+ if (!emc_enable) {
+ dev_err(&pdev->dev, "disabled per module parameter\n");
+ return -ENODEV;
+ }
+
+ pdata = pdev->dev.platform_data;
- emc_readl(tegra_emc_table[i].regs[TEGRA_EMC_NUM_REGS - 1]);
+ if (!pdata) {
+ dev_err(&pdev->dev, "missing platform data\n");
+ return -ENXIO;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "missing register base\n");
+ return -ENOMEM;
+ }
+
+ emc_regbase = devm_request_and_ioremap(&pdev->dev, res);
+ if (!emc_regbase) {
+ dev_err(&pdev->dev, "failed to remap registers\n");
+ return -ENOMEM;
+ }
+ emc_pdev = pdev;
return 0;
}
-void tegra_init_emc(const struct tegra_emc_table *table, int table_size)
+static struct platform_driver tegra_emc_driver = {
+ .driver = {
+ .name = "tegra-emc",
+ .owner = THIS_MODULE,
+ },
+ .probe = tegra_emc_probe,
+};
+
+static int __init tegra_emc_init(void)
{
- tegra_emc_table = table;
- tegra_emc_table_size = table_size;
+ return platform_driver_register(&tegra_emc_driver);
}
+device_initcall(tegra_emc_init);
diff --git a/arch/arm/mach-tegra/tegra2_emc.h b/arch/arm/mach-tegra/tegra2_emc.h
index 19f08cb..f61409b 100644
--- a/arch/arm/mach-tegra/tegra2_emc.h
+++ b/arch/arm/mach-tegra/tegra2_emc.h
@@ -15,13 +15,10 @@
*
*/
-#define TEGRA_EMC_NUM_REGS 46
-
-struct tegra_emc_table {
- unsigned long rate;
- u32 regs[TEGRA_EMC_NUM_REGS];
-};
+#ifndef __MACH_TEGRA_TEGRA2_EMC_H_
+#define __MACH_TEGRA_TEGRA2_EMC_H
int tegra_emc_set_rate(unsigned long rate);
long tegra_emc_round_rate(unsigned long rate);
-void tegra_init_emc(const struct tegra_emc_table *table, int table_size);
+
+#endif
diff --git a/include/linux/platform_data/tegra_emc.h b/include/linux/platform_data/tegra_emc.h
new file mode 100644
index 0000000..df67505
--- /dev/null
+++ b/include/linux/platform_data/tegra_emc.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>
+ * Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
+ *
+ * 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 __TEGRA_EMC_H_
+#define __TEGRA_EMC_H_
+
+#define TEGRA_EMC_NUM_REGS 46
+
+struct tegra_emc_table {
+ unsigned long rate;
+ u32 regs[TEGRA_EMC_NUM_REGS];
+};
+
+struct tegra_emc_pdata {
+ int num_tables;
+ struct tegra_emc_table *tables;
+};
+
+#endif
--
1.7.8.GIT
^ permalink raw reply related [flat|nested] 45+ messages in thread
* RE: [PATCH v4] ARM: tegra: emc: convert tegra2_emc to a platform driver
[not found] ` <1325814163-23980-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
@ 2012-01-06 17:17 ` Stephen Warren
0 siblings, 0 replies; 45+ messages in thread
From: Stephen Warren @ 2012-01-06 17:17 UTC (permalink / raw)
To: Olof Johansson,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Olof Johansson wrote at Thursday, January 05, 2012 6:43 PM:
> This is the first step in making it device-tree aware and get rid of the
> in-kernel EMC tables (of which there are none in mainline, thankfully).
>
> Changes since v3:
>
> * moved to devm_request_and_ioremap() in probe()
> *
> Changes since v2:
>
> * D'oh -- missed a couple of variables that were added, never used and then
> later removed in a later patch.
>
> Changes since v1:
>
> * Fixed messed up indentation
> * Removed code that should be gone (was added here and removed later in series)
>
> Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
Acked-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
--
nvpublic
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 7/9] arm/tegra: emc: device tree bindings
[not found] ` <CAOesGMjeVm_PcsBnxfKX9Oe96QUaCsJrvuESCRZq5vwq9gD5xA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-01-12 20:03 ` Simon Glass
[not found] ` <CAPnjgZ2p63C1UNr_RxCcwKjjqJFXzZppXD14hXh85zXH35POrw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 45+ messages in thread
From: Simon Glass @ 2012-01-12 20:03 UTC (permalink / raw)
To: Olof Johansson
Cc: Stephen Warren,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org
Hi Olof,
On Thu, Jan 5, 2012 at 5:20 PM, Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org> wrote:
> On Thu, Jan 5, 2012 at 4:01 PM, Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
>> Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
>>> Device tree bindings for the EMC tables on tegra.
>> ...
>>> diff --git a/Documentation/devicetree/bindings/arm/tegra/emc.txt
>> ...
>>> +Embedded Memory Controller ram-code table
>> ...
>>> +- name : Should be emc-tables
>>> +- nvidia,ram-code : the binary representation of the ram-code board strappings
>>> + for which this node (and children) are valid.
>> ...
>>> +Embedded Memory Controller configuration table
>> ...
>>> +- name : Should be emc-table
>>> +- compatible : Should contain "nvidia,tegra20-emc-table".
>>> +- reg : either an opaque enumerator to tell different tables apart, or
>> ...
>>
>> One more thought:
>>
>> For consistency, should the "emc-tables" node also require a compatible
>> value? I suppose the existence of an "nvidia,ram-code" property is quite
>> likely to be indication enough that the node is compatible, but I wonder
>> if we shouldn't require and check an explicit compatible value at this
>> level too?
>
> I can add it, it's trivial to add another check in
> tegra_emc_ramcode_devnode, but I don't think there's much need to
> bother. As long as nothing else is added that uses nvidia,ram-code as
> a property we'll be OK, and we can control that.
I am looking at maybe bringing this into U-Boot.
Do you have an example of the ram-code table? Would it look something like this?
emc@7000f400 {
#address-cells = < 1 >;
#size-cells = < 0 >;
compatible = "nvidia,tegra20-emc";
reg = <0x7000f4000 0x200>;
nvidia,use-ram-code;
emc-tables@0 {
nvidia,ram-code = <0>;
compatible = "nvidia,tegra20-emc-tables";
emc-table@166000 {
reg = <166000>;
compatible = "nvidia,tegra20-emc-table";
clock-frequency = < 166000 >;
nvidia,emc-registers = < 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 >;
};
};
emc-tables@1 {
nvidia,ram-code = <1>;
compatible = "nvidia,tegra20-emc-tables";
emc-table@333000 {
reg = <333000>;
compatible = "nvidia,tegra20-emc-table";
clock-frequency = < 333000 >;
nvidia,emc-registers = < 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 >;
};
};
... @2, @3 follow
};
Also, can/should we be able to specify a frequency to override the strapping?
Regards,
Simon
>
>
> -Olof
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
^ permalink raw reply [flat|nested] 45+ messages in thread
* RE: [PATCH 7/9] arm/tegra: emc: device tree bindings
[not found] ` <CAPnjgZ2p63C1UNr_RxCcwKjjqJFXzZppXD14hXh85zXH35POrw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-01-12 20:50 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17801D1DCF-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
0 siblings, 1 reply; 45+ messages in thread
From: Stephen Warren @ 2012-01-12 20:50 UTC (permalink / raw)
To: Simon Glass, Olof Johansson
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org
Simon Glass wrote at Thursday, January 12, 2012 1:04 PM:
> On Thu, Jan 5, 2012 at 5:20 PM, Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org> wrote:
> > On Thu, Jan 5, 2012 at 4:01 PM, Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> >> Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
> >>> Device tree bindings for the EMC tables on tegra.
...
> I am looking at maybe bringing this into U-Boot.
>
> Do you have an example of the ram-code table? Would it look something like this?
There's an example for Seaboard here:
http://patchwork.ozlabs.org/patch/132929/
The base EMC node was added earlier in the patch series:
http://patchwork.ozlabs.org/patch/132928/
--
nvpublic
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 7/9] arm/tegra: emc: device tree bindings
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17801D1DCF-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
@ 2012-01-12 21:01 ` Simon Glass
0 siblings, 0 replies; 45+ messages in thread
From: Simon Glass @ 2012-01-12 21:01 UTC (permalink / raw)
To: Stephen Warren
Cc: Olof Johansson,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org
Hi Stephen,
On Thu, Jan 12, 2012 at 12:50 PM, Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> Simon Glass wrote at Thursday, January 12, 2012 1:04 PM:
>> On Thu, Jan 5, 2012 at 5:20 PM, Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org> wrote:
>> > On Thu, Jan 5, 2012 at 4:01 PM, Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
>> >> Olof Johansson wrote at Thursday, December 22, 2011 5:18 PM:
>> >>> Device tree bindings for the EMC tables on tegra.
> ...
>> I am looking at maybe bringing this into U-Boot.
>>
>> Do you have an example of the ram-code table? Would it look something like this?
>
> There's an example for Seaboard here:
>
> http://patchwork.ozlabs.org/patch/132929/
>
> The base EMC node was added earlier in the patch series:
>
> http://patchwork.ozlabs.org/patch/132928/
Thanks for that. There is a single level example, but from what I can
tell it will do fine for U-Boot.
Regards,
Simon
>
> --
> nvpublic
>
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH 7/9] arm/tegra: emc: device tree bindings
[not found] ` <1324599468-12845-8-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-02 9:00 ` Grant Likely
2012-01-06 0:01 ` Stephen Warren
@ 2012-01-12 21:48 ` Simon Glass
2 siblings, 0 replies; 45+ messages in thread
From: Simon Glass @ 2012-01-12 21:48 UTC (permalink / raw)
To: Olof Johansson
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
ccross-z5hGa2qSFaRBDgjK7y7TUQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Hi Olof,
On Thu, Dec 22, 2011 at 4:17 PM, Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org> wrote:
> Device tree bindings for the EMC tables on tegra.
>
> Signed-off-by: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
> Cc: Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> ---
> .../devicetree/bindings/arm/tegra/emc.txt | 100 ++++++++++++++++++++
> arch/arm/boot/dts/tegra20.dtsi | 7 ++
> 2 files changed, 107 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/arm/tegra/emc.txt
>
> diff --git a/Documentation/devicetree/bindings/arm/tegra/emc.txt b/Documentation/devicetree/bindings/arm/tegra/emc.txt
> new file mode 100644
> index 0000000..09335f8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/tegra/emc.txt
> @@ -0,0 +1,100 @@
> +Embedded Memory Controller
> +
> +Properties:
> +- name : Should be emc
> +- #address-cells : Should be 1
> +- #size-cells : Should be 0
> +- compatible : Should contain "nvidia,tegra20-emc".
> +- reg : Offset and length of the register set for the device
> +- nvidia,use-ram-code : If present, the sub-nodes will be addressed
> + and chosen using the ramcode board selector. If omitted, only one
> + set of tables can be present and said tables will be used
> + irrespective of ram-code configuration.
> +
> +Child device nodes describe the memory settings for different configurations and clock rates.
> +
> +Example:
> +
> + emc@7000f400 {
> + #address-cells = < 1 >;
> + #size-cells = < 0 >;
> + compatible = "nvidia,tegra20-emc";
> + reg = <0x7000f4000 0x200>;
Minor point - that should be 0x7000f400.
Regards,
SImon
^ permalink raw reply [flat|nested] 45+ messages in thread
end of thread, other threads:[~2012-01-12 21:48 UTC | newest]
Thread overview: 45+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-23 0:17 [PATCH 0/9] arm/tegra: fuse cleanup and emc device tree support Olof Johansson
[not found] ` <1324599468-12845-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2011-12-23 0:17 ` [PATCH 1/9] arm/tegra: Don't WARN_ON() for too early dma channel allocations Olof Johansson
2011-12-23 0:17 ` [PATCH 2/9] arm/tegra: use APB DMA for accessing APB devices Olof Johansson
[not found] ` <1324599468-12845-3-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-04 22:08 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F14F6-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-04 23:39 ` Olof Johansson
2012-01-05 5:49 ` [PATCH v2] " Olof Johansson
[not found] ` <1325742554-32735-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-05 22:07 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F1812-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-06 1:22 ` Olof Johansson
2011-12-23 0:17 ` [PATCH 3/9] arm/tegra: fuse: use apbio dma for register access Olof Johansson
2011-12-23 0:17 ` [PATCH 4/9] arm/tegra: fuse: add functions to access chip revision Olof Johansson
2011-12-23 10:47 ` Henning Heinold
[not found] ` <20111223104751.GA22157-RGm7CqJPa6S97g7+dlk11ZJjESxClBkh@public.gmane.org>
2012-01-04 3:46 ` Olof Johansson
[not found] ` <1324599468-12845-5-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-04 23:20 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F156A-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-04 23:36 ` Olof Johansson
2012-01-05 5:50 ` [PATCH v2] " Olof Johansson
[not found] ` <1325742641-384-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-05 22:08 ` Stephen Warren
2011-12-23 0:17 ` [PATCH 5/9] arm/tegra: fuse: add bct strapping reading Olof Johansson
2011-12-23 0:17 ` [PATCH 6/9] arm/tegra: emc: convert tegra2_emc to a platform driver Olof Johansson
[not found] ` <1324599468-12845-7-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-04 23:39 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F158A-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-04 23:42 ` Olof Johansson
2012-01-05 5:56 ` [PATCH v2] " Olof Johansson
[not found] ` <1325742994-1178-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-05 6:01 ` [PATCH v3] " Olof Johansson
[not found] ` <1325743288-2460-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-05 22:14 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F1818-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-06 1:36 ` Olof Johansson
2012-01-06 1:42 ` [PATCH v4] ARM: tegra: " Olof Johansson
[not found] ` <1325814163-23980-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-06 17:17 ` Stephen Warren
2011-12-23 0:17 ` [PATCH 7/9] arm/tegra: emc: device tree bindings Olof Johansson
[not found] ` <1324599468-12845-8-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-02 9:00 ` Grant Likely
2012-01-06 0:01 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F18A6-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-06 1:20 ` Olof Johansson
[not found] ` <CAOesGMjeVm_PcsBnxfKX9Oe96QUaCsJrvuESCRZq5vwq9gD5xA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-01-12 20:03 ` Simon Glass
[not found] ` <CAPnjgZ2p63C1UNr_RxCcwKjjqJFXzZppXD14hXh85zXH35POrw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-01-12 20:50 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17801D1DCF-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-12 21:01 ` Simon Glass
2012-01-12 21:48 ` Simon Glass
2011-12-23 0:17 ` [PATCH 8/9] arm/tegra: seaboard: add EMC table to device tree Olof Johansson
[not found] ` <1324599468-12845-9-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-04 23:51 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F1590-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-04 23:55 ` Olof Johansson
[not found] ` <CAOesGMhROzwyqMS89Nq0m6KRLNTbrkFrH9pUe6tfPR8gKTU+QA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-01-05 0:11 ` Linus Walleij
[not found] ` <CACRpkdbtY+vOc-X8Ay1RyN61Xseepc2X-NnvFe=G++ASwrpOxQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-01-05 5:43 ` Olof Johansson
2011-12-23 0:17 ` [PATCH 9/9] arm/tegra: emc: device tree support Olof Johansson
[not found] ` <1324599468-12845-10-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-05 0:27 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F15B3-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-05 0:35 ` Olof Johansson
2012-01-05 6:02 ` [PATCH v2] " Olof Johansson
[not found] ` <1325743338-2533-1-git-send-email-olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
2012-01-05 22:35 ` Stephen Warren
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17761F182F-C7FfzLzN0UxDw2glCA4ptUEOCMrvLtNR@public.gmane.org>
2012-01-06 1:26 ` Olof Johansson
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).