* [PATCH 1/8] Add set_dma_ops() to match get_dma_ops().
From: Michael Ellerman @ 2008-01-29 14:13 UTC (permalink / raw)
To: linuxppc-dev; +Cc: cbe-oss-dev
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
include/asm-powerpc/dma-mapping.h | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index 5eea6db..bbefb69 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -76,6 +76,11 @@ static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
return dev->archdata.dma_ops;
}
+static inline void set_dma_ops(struct device *dev, struct dma_mapping_ops *ops)
+{
+ dev->archdata.dma_ops = ops;
+}
+
static inline int dma_supported(struct device *dev, u64 mask)
{
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
--
1.5.3.7.1.g4e596e
^ permalink raw reply related
* [PATCH 2/8] Allocate the hash table under 1G on cell
From: Michael Ellerman @ 2008-01-29 14:13 UTC (permalink / raw)
To: linuxppc-dev; +Cc: cbe-oss-dev
In-Reply-To: <56662c291890f09835ef7251f9b86f70fbee3ad2.1201616038.git.michael@ellerman.id.au>
In order to support the fixed IOMMU mapping (in a subsequent patch), we
need the hash table to be inside the IOMMUs DMA window. This is usually 2G,
but let's make sure the hash table is under 1G as that will satisfy the
IOMMU requirements and also means the hash table will be on node 0.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/mm/hash_utils_64.c | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 9326a69..487c5e2 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -471,7 +471,7 @@ void __init htab_initialize(void)
unsigned long table;
unsigned long pteg_count;
unsigned long mode_rw;
- unsigned long base = 0, size = 0;
+ unsigned long base = 0, size = 0, limit;
int i;
extern unsigned long tce_alloc_start, tce_alloc_end;
@@ -505,9 +505,15 @@ void __init htab_initialize(void)
_SDR1 = 0;
} else {
/* Find storage for the HPT. Must be contiguous in
- * the absolute address space.
+ * the absolute address space. On cell we want it to be
+ * in the first 1 Gig.
*/
- table = lmb_alloc(htab_size_bytes, htab_size_bytes);
+ if (machine_is(cell))
+ limit = 0x40000000;
+ else
+ limit = 0;
+
+ table = lmb_alloc_base(htab_size_bytes, htab_size_bytes, limit);
DBG("Hash table allocated at %lx, size: %lx\n", table,
htab_size_bytes);
--
1.5.3.7.1.g4e596e
^ permalink raw reply related
* [PATCH 3/8] Split out the logic that allocates struct iommus
From: Michael Ellerman @ 2008-01-29 14:13 UTC (permalink / raw)
To: linuxppc-dev; +Cc: cbe-oss-dev
In-Reply-To: <56662c291890f09835ef7251f9b86f70fbee3ad2.1201616038.git.michael@ellerman.id.au>
Split out the logic that allocates a struct iommu into a separate
function. This can fail however the calling code has never cared - so
just return if we can't allocate an iommu.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/cell/iommu.c | 20 ++++++++++++++++----
1 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 9223559..4f1ca43 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -565,10 +565,9 @@ static int __init cell_iommu_get_window(struct device_node *np,
return 0;
}
-static void __init cell_iommu_init_one(struct device_node *np, unsigned long offset)
+static struct cbe_iommu * __init cell_iommu_alloc(struct device_node *np)
{
struct cbe_iommu *iommu;
- unsigned long base, size;
int nid, i;
/* Get node ID */
@@ -576,7 +575,7 @@ static void __init cell_iommu_init_one(struct device_node *np, unsigned long off
if (nid < 0) {
printk(KERN_ERR "iommu: failed to get node for %s\n",
np->full_name);
- return;
+ return NULL;
}
pr_debug("iommu: setting up iommu for node %d (%s)\n",
nid, np->full_name);
@@ -592,7 +591,7 @@ static void __init cell_iommu_init_one(struct device_node *np, unsigned long off
if (cbe_nr_iommus >= NR_IOMMUS) {
printk(KERN_ERR "iommu: too many IOMMUs detected ! (%s)\n",
np->full_name);
- return;
+ return NULL;
}
/* Init base fields */
@@ -603,6 +602,19 @@ static void __init cell_iommu_init_one(struct device_node *np, unsigned long off
snprintf(iommu->name, sizeof(iommu->name), "iommu%d", i);
INIT_LIST_HEAD(&iommu->windows);
+ return iommu;
+}
+
+static void __init cell_iommu_init_one(struct device_node *np,
+ unsigned long offset)
+{
+ struct cbe_iommu *iommu;
+ unsigned long base, size;
+
+ iommu = cell_iommu_alloc(np);
+ if (!iommu)
+ return;
+
/* Obtain a window for it */
cell_iommu_get_window(np, &base, &size);
--
1.5.3.7.1.g4e596e
^ permalink raw reply related
* [PATCH 4/8] Split cell_iommu_setup_hardware() into two parts
From: Michael Ellerman @ 2008-01-29 14:14 UTC (permalink / raw)
To: linuxppc-dev; +Cc: cbe-oss-dev
In-Reply-To: <56662c291890f09835ef7251f9b86f70fbee3ad2.1201616038.git.michael@ellerman.id.au>
Split cell_iommu_setup_hardware() into two parts. Split the page table
setup into cell_iommu_setup_page_tables() and the bits that kick the
hardware into cell_iommu_enable_hardware().
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/cell/iommu.c | 38 +++++++++++++++++++++++-----------
1 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 4f1ca43..a86e5bb 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -306,20 +306,13 @@ static int cell_iommu_find_ioc(int nid, unsigned long *base)
return -ENODEV;
}
-static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, unsigned long size)
+static void cell_iommu_setup_page_tables(struct cbe_iommu *iommu,
+ unsigned long base, unsigned long size)
{
struct page *page;
- int ret, i;
+ int i;
unsigned long reg, segments, pages_per_segment, ptab_size, stab_size,
- n_pte_pages, xlate_base;
- unsigned int virq;
-
- if (cell_iommu_find_ioc(iommu->nid, &xlate_base))
- panic("%s: missing IOC register mappings for node %d\n",
- __FUNCTION__, iommu->nid);
-
- iommu->xlate_regs = ioremap(xlate_base, IOC_Reg_Size);
- iommu->cmd_regs = iommu->xlate_regs + IOC_IOCmd_Offset;
+ n_pte_pages;
segments = size >> IO_SEGMENT_SHIFT;
pages_per_segment = 1ull << IO_PAGENO_BITS;
@@ -378,6 +371,20 @@ static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, unsigned long siz
(__pa(iommu->ptab) + n_pte_pages * IOMMU_PAGE_SIZE * i);
pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]);
}
+}
+
+static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
+{
+ int ret;
+ unsigned long reg, xlate_base;
+ unsigned int virq;
+
+ if (cell_iommu_find_ioc(iommu->nid, &xlate_base))
+ panic("%s: missing IOC register mappings for node %d\n",
+ __FUNCTION__, iommu->nid);
+
+ iommu->xlate_regs = ioremap(xlate_base, IOC_Reg_Size);
+ iommu->cmd_regs = iommu->xlate_regs + IOC_IOCmd_Offset;
/* ensure that the STEs have updated */
mb();
@@ -407,6 +414,13 @@ static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, unsigned long siz
out_be64(iommu->cmd_regs + IOC_IOCmd_Cfg, reg);
}
+static void cell_iommu_setup_hardware(struct cbe_iommu *iommu,
+ unsigned long base, unsigned long size)
+{
+ cell_iommu_setup_page_tables(iommu, base, size);
+ cell_iommu_enable_hardware(iommu);
+}
+
#if 0/* Unused for now */
static struct iommu_window *find_window(struct cbe_iommu *iommu,
unsigned long offset, unsigned long size)
@@ -622,7 +636,7 @@ static void __init cell_iommu_init_one(struct device_node *np,
base, base + size - 1);
/* Initialize the hardware */
- cell_iommu_setup_hardware(iommu, size);
+ cell_iommu_setup_hardware(iommu, base, size);
/* Setup the iommu_table */
cell_iommu_setup_window(iommu, np, base, size,
--
1.5.3.7.1.g4e596e
^ permalink raw reply related
* [PATCH 5/8] Split out the IOMMU logic from cell_dma_dev_setup()
From: Michael Ellerman @ 2008-01-29 14:14 UTC (permalink / raw)
To: linuxppc-dev; +Cc: cbe-oss-dev
In-Reply-To: <56662c291890f09835ef7251f9b86f70fbee3ad2.1201616038.git.michael@ellerman.id.au>
Split the IOMMU logic out from cell_dma_dev_setup() into a separate
function. If we're not using dma_direct_ops or dma_iommu_ops we don't
know what the hell's going on, so BUG.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/cell/iommu.c | 19 +++++++++++++------
1 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index a86e5bb..e9769fc 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -507,17 +507,12 @@ static struct cbe_iommu *cell_iommu_for_node(int nid)
static unsigned long cell_dma_direct_offset;
-static void cell_dma_dev_setup(struct device *dev)
+static void cell_dma_dev_setup_iommu(struct device *dev)
{
struct iommu_window *window;
struct cbe_iommu *iommu;
struct dev_archdata *archdata = &dev->archdata;
- if (get_pci_dma_ops() == &dma_direct_ops) {
- archdata->dma_data = (void *)cell_dma_direct_offset;
- return;
- }
-
/* Current implementation uses the first window available in that
* node's iommu. We -might- do something smarter later though it may
* never be necessary
@@ -534,6 +529,18 @@ static void cell_dma_dev_setup(struct device *dev)
archdata->dma_data = &window->table;
}
+static void cell_dma_dev_setup(struct device *dev)
+{
+ struct dev_archdata *archdata = &dev->archdata;
+
+ if (get_pci_dma_ops() == &dma_iommu_ops)
+ cell_dma_dev_setup_iommu(dev);
+ else if (get_pci_dma_ops() == &dma_direct_ops)
+ archdata->dma_data = (void *)cell_dma_direct_offset;
+ else
+ BUG();
+}
+
static void cell_pci_dma_dev_setup(struct pci_dev *dev)
{
cell_dma_dev_setup(&dev->dev);
--
1.5.3.7.1.g4e596e
^ permalink raw reply related
* [PATCH 6/8] Add support to cell_iommu_setup_page_tables() for multiple windows
From: Michael Ellerman @ 2008-01-29 14:14 UTC (permalink / raw)
To: linuxppc-dev; +Cc: cbe-oss-dev
In-Reply-To: <56662c291890f09835ef7251f9b86f70fbee3ad2.1201616038.git.michael@ellerman.id.au>
Add support to cell_iommu_setup_page_tables() for handling two windows,
the dynamic window and the fixed window. A fixed window size of 0
indicates that there is no fixed window at all.
Currently there are no callers who pass a non-zero fixed window, but the
upcoming fixed IOMMU mapping patch will change that.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/cell/iommu.c | 15 ++++++++++-----
1 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index e9769fc..7779dbf 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -307,14 +307,19 @@ static int cell_iommu_find_ioc(int nid, unsigned long *base)
}
static void cell_iommu_setup_page_tables(struct cbe_iommu *iommu,
- unsigned long base, unsigned long size)
+ unsigned long dbase, unsigned long dsize,
+ unsigned long fbase, unsigned long fsize)
{
struct page *page;
int i;
unsigned long reg, segments, pages_per_segment, ptab_size, stab_size,
- n_pte_pages;
+ n_pte_pages, base;
- segments = size >> IO_SEGMENT_SHIFT;
+ base = dbase;
+ if (fsize != 0)
+ base = min(fbase, dbase);
+
+ segments = max(dbase + dsize, fbase + fsize) >> IO_SEGMENT_SHIFT;
pages_per_segment = 1ull << IO_PAGENO_BITS;
pr_debug("%s: iommu[%d]: segments: %lu, pages per segment: %lu\n",
@@ -366,7 +371,7 @@ static void cell_iommu_setup_page_tables(struct cbe_iommu *iommu,
}
pr_debug("Setting up IOMMU stab:\n");
- for (i = 0; i * (1ul << IO_SEGMENT_SHIFT) < size; i++) {
+ for (i = base >> IO_SEGMENT_SHIFT; i < segments; i++) {
iommu->stab[i] = reg |
(__pa(iommu->ptab) + n_pte_pages * IOMMU_PAGE_SIZE * i);
pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]);
@@ -417,7 +422,7 @@ static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
static void cell_iommu_setup_hardware(struct cbe_iommu *iommu,
unsigned long base, unsigned long size)
{
- cell_iommu_setup_page_tables(iommu, base, size);
+ cell_iommu_setup_page_tables(iommu, base, size, 0, 0);
cell_iommu_enable_hardware(iommu);
}
--
1.5.3.7.1.g4e596e
^ permalink raw reply related
* [PATCH 7/8] Split out the ioid fetching/checking logic
From: Michael Ellerman @ 2008-01-29 14:14 UTC (permalink / raw)
To: linuxppc-dev; +Cc: cbe-oss-dev
In-Reply-To: <56662c291890f09835ef7251f9b86f70fbee3ad2.1201616038.git.michael@ellerman.id.au>
Split out the ioid fetching and checking logic so we can use it elsewhere
in a subsequent patch.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/cell/iommu.c | 23 +++++++++++++++++------
1 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 7779dbf..3baade1 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -443,25 +443,36 @@ static struct iommu_window *find_window(struct cbe_iommu *iommu,
}
#endif
+static inline u32 cell_iommu_get_ioid(struct device_node *np)
+{
+ const u32 *ioid;
+
+ ioid = of_get_property(np, "ioid", NULL);
+ if (ioid == NULL) {
+ printk(KERN_WARNING "iommu: missing ioid for %s using 0\n",
+ np->full_name);
+ return 0;
+ }
+
+ return *ioid;
+}
+
static struct iommu_window * __init
cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
unsigned long offset, unsigned long size,
unsigned long pte_offset)
{
struct iommu_window *window;
- const unsigned int *ioid;
+ u32 ioid;
- ioid = of_get_property(np, "ioid", NULL);
- if (ioid == NULL)
- printk(KERN_WARNING "iommu: missing ioid for %s using 0\n",
- np->full_name);
+ ioid = cell_iommu_get_ioid(np);
window = kmalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid);
BUG_ON(window == NULL);
window->offset = offset;
window->size = size;
- window->ioid = ioid ? *ioid : 0;
+ window->ioid = ioid;
window->iommu = iommu;
window->pte_offset = pte_offset;
--
1.5.3.7.1.g4e596e
^ permalink raw reply related
* [PATCH 8/8] Cell IOMMU fixed mapping support
From: Michael Ellerman @ 2008-01-29 14:14 UTC (permalink / raw)
To: linuxppc-dev; +Cc: cbe-oss-dev
In-Reply-To: <56662c291890f09835ef7251f9b86f70fbee3ad2.1201616038.git.michael@ellerman.id.au>
This patch adds support for setting up a fixed IOMMU mapping on certain
cell machines. For 64-bit devices this avoids the performance overhead of
mapping and unmapping pages at runtime. 32-bit devices are unable to use
the fixed mapping.
The fixed mapping is established at boot, and maps all of physical memory
1:1 into device space at some offset. On machines with < 30 GB of memory
we setup the fixed mapping immediately above the normal IOMMU window.
For example a machine with 4GB of memory would end up with the normal
IOMMU window from 0-2GB and the fixed mapping window from 2GB to 6GB. In
this case a 64-bit device wishing to DMA to 1GB would be told to DMA to
3GB, plus any offset required by firmware. The firmware offset is encoded
in the "dma-ranges" property.
On machines with 30GB or more of memory, we are unable to place the fixed
mapping above the normal IOMMU window as we would run out of address space.
Instead we move the normal IOMMU window to coincide with the hash page
table, this region does not need to be part of the fixed mapping as no
device should ever be DMA'ing to it. We then setup the fixed mapping
from 0 to 32GB.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/cell/iommu.c | 241 ++++++++++++++++++++++++++++++++++-
1 files changed, 240 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 3baade1..56c69cc 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -523,6 +523,9 @@ static struct cbe_iommu *cell_iommu_for_node(int nid)
static unsigned long cell_dma_direct_offset;
+static unsigned long dma_iommu_fixed_base;
+struct dma_mapping_ops dma_iommu_fixed_ops;
+
static void cell_dma_dev_setup_iommu(struct device *dev)
{
struct iommu_window *window;
@@ -545,11 +548,16 @@ static void cell_dma_dev_setup_iommu(struct device *dev)
archdata->dma_data = &window->table;
}
+static void cell_dma_dev_setup_static(struct device *dev);
+
static void cell_dma_dev_setup(struct device *dev)
{
struct dev_archdata *archdata = &dev->archdata;
- if (get_pci_dma_ops() == &dma_iommu_ops)
+ /* Order is important here, these are not mutually exclusive */
+ if (get_dma_ops(dev) == &dma_iommu_fixed_ops)
+ cell_dma_dev_setup_static(dev);
+ else if (get_pci_dma_ops() == &dma_iommu_ops)
cell_dma_dev_setup_iommu(dev);
else if (get_pci_dma_ops() == &dma_direct_ops)
archdata->dma_data = (void *)cell_dma_direct_offset;
@@ -752,6 +760,234 @@ static int __init cell_iommu_init_disabled(void)
return 0;
}
+static u64 cell_iommu_get_fixed_address(struct device *dev)
+{
+ u64 cpu_addr, size, best_size, pci_addr = OF_BAD_ADDR;
+ struct device_node *tmp, *np;
+ const u32 *ranges = NULL;
+ int i, len, best;
+
+ np = dev->archdata.of_node;
+ of_node_get(np);
+ ranges = of_get_property(np, "dma-ranges", &len);
+ while (!ranges && np) {
+ tmp = of_get_parent(np);
+ of_node_put(np);
+ np = tmp;
+ ranges = of_get_property(np, "dma-ranges", &len);
+ }
+
+ if (!ranges) {
+ dev_dbg(dev, "iommu: no dma-ranges found\n");
+ goto out;
+ }
+
+ len /= sizeof(u32);
+
+ /* dma-ranges format:
+ * 1 cell: pci space
+ * 2 cells: pci address
+ * 2 cells: parent address
+ * 2 cells: size
+ */
+ for (i = 0, best = -1, best_size = 0; i < len; i += 7) {
+ cpu_addr = of_translate_dma_address(np, ranges +i + 3);
+ size = of_read_number(ranges + i + 5, 2);
+
+ if (cpu_addr == 0 && size > best_size) {
+ best = i;
+ best_size = size;
+ }
+ }
+
+ if (best >= 0)
+ pci_addr = of_read_number(ranges + best + 1, 2);
+ else
+ dev_dbg(dev, "iommu: no suitable range found!\n");
+
+out:
+ of_node_put(np);
+
+ return pci_addr;
+}
+
+static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask)
+{
+ if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+ return -EIO;
+
+ if (dma_mask == DMA_BIT_MASK(64)) {
+ if (cell_iommu_get_fixed_address(dev) == OF_BAD_ADDR)
+ dev_dbg(dev, "iommu: 64-bit OK, but bad addr\n");
+ else {
+ dev_dbg(dev, "iommu: 64-bit OK, using fixed ops\n");
+ set_dma_ops(dev, &dma_iommu_fixed_ops);
+ cell_dma_dev_setup(dev);
+ }
+ } else {
+ dev_dbg(dev, "iommu: not 64-bit, using default ops\n");
+ set_dma_ops(dev, get_pci_dma_ops());
+ }
+
+ *dev->dma_mask = dma_mask;
+
+ return 0;
+}
+
+static void cell_dma_dev_setup_static(struct device *dev)
+{
+ struct dev_archdata *archdata = &dev->archdata;
+ u64 addr;
+
+ addr = cell_iommu_get_fixed_address(dev) + dma_iommu_fixed_base;
+ archdata->dma_data = (void *)addr;
+
+ dev_dbg(dev, "iommu: fixed addr = %lx\n", addr);
+}
+
+static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
+ struct device_node *np, unsigned long dbase, unsigned long dsize,
+ unsigned long fbase, unsigned long fsize)
+{
+ unsigned long base_pte, uaddr, *io_pte;
+ int i;
+
+ dma_iommu_fixed_base = fbase;
+
+ /* convert from bytes into page table indices */
+ dbase = dbase >> IOMMU_PAGE_SHIFT;
+ dsize = dsize >> IOMMU_PAGE_SHIFT;
+ fbase = fbase >> IOMMU_PAGE_SHIFT;
+ fsize = fsize >> IOMMU_PAGE_SHIFT;
+
+ pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase);
+
+ io_pte = iommu->ptab;
+ base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW
+ | (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask);
+
+ uaddr = 0;
+ for (i = fbase; i < fbase + fsize; i++, uaddr += IOMMU_PAGE_SIZE) {
+ /* Don't touch the dynamic region */
+ if (i >= dbase && i < (dbase + dsize)) {
+ pr_debug("iommu: static/dynamic overlap, skipping\n");
+ continue;
+ }
+ io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
+ }
+
+ mb();
+}
+
+static int __init cell_iommu_fixed_mapping_init(void)
+{
+ unsigned long dbase, dsize, fbase, fsize, hbase, hend;
+ struct cbe_iommu *iommu;
+ struct device_node *np;
+
+ /* The fixed mapping is only supported on axon machines */
+ np = of_find_node_by_name(NULL, "axon");
+ if (!np) {
+ pr_debug("iommu: fixed mapping disabled, no axons found\n");
+ return -1;
+ }
+
+ /* The default setup is to have the fixed mapping sit after the
+ * dynamic region, so find the top of the largest IOMMU window
+ * on any axon, then add the size of RAM and that's our max value.
+ * If that is > 32GB we have to do other shennanigans.
+ */
+ fbase = 0;
+ for_each_node_by_name(np, "axon") {
+ cell_iommu_get_window(np, &dbase, &dsize);
+ fbase = max(fbase, dbase + dsize);
+ }
+
+ fbase = _ALIGN_UP(fbase, 1 << IO_SEGMENT_SHIFT);
+ fsize = lmb_phys_mem_size();
+
+ if ((fbase + fsize) <= 0x800000000)
+ hbase = 0; /* use the device tree window */
+ else {
+ /* If we're over 32 GB we need to cheat. We can't map all of
+ * RAM with the fixed mapping, and also fit the dynamic
+ * region. So try to place the dynamic region where the hash
+ * table sits, drivers never need to DMA to it, we don't
+ * need a fixed mapping for that area.
+ */
+ if (!htab_address) {
+ pr_debug("iommu: htab is NULL, on LPAR? Huh?\n");
+ return -1;
+ }
+ hbase = __pa(htab_address);
+ hend = hbase + htab_size_bytes;
+
+ /* The window must start and end on a segment boundary */
+ if ((hbase != _ALIGN_UP(hbase, 1 << IO_SEGMENT_SHIFT)) ||
+ (hend != _ALIGN_UP(hend, 1 << IO_SEGMENT_SHIFT))) {
+ pr_debug("iommu: hash window not segment aligned\n");
+ return -1;
+ }
+
+ /* Check the hash window fits inside the real DMA window */
+ for_each_node_by_name(np, "axon") {
+ cell_iommu_get_window(np, &dbase, &dsize);
+
+ if (hbase < dbase || (hend > (dbase + dsize))) {
+ pr_debug("iommu: hash window doesn't fit in"
+ "real DMA window\n");
+ return -1;
+ }
+ }
+
+ fbase = 0;
+ }
+
+ /* Setup the dynamic regions */
+ for_each_node_by_name(np, "axon") {
+ iommu = cell_iommu_alloc(np);
+ BUG_ON(!iommu);
+
+ if (hbase == 0)
+ cell_iommu_get_window(np, &dbase, &dsize);
+ else {
+ dbase = hbase;
+ dsize = htab_size_bytes;
+ }
+
+ pr_debug("iommu: setting up %d, dynamic window %lx-%lx " \
+ "fixed window %lx-%lx\n", iommu->nid, dbase,
+ dbase + dsize, fbase, fbase + fsize);
+
+ cell_iommu_setup_page_tables(iommu, dbase, dsize, fbase, fsize);
+ cell_iommu_setup_fixed_ptab(iommu, np, dbase, dsize,
+ fbase, fsize);
+ cell_iommu_enable_hardware(iommu);
+ cell_iommu_setup_window(iommu, np, dbase, dsize, 0);
+ }
+
+ dma_iommu_fixed_ops = dma_direct_ops;
+ dma_iommu_fixed_ops.set_dma_mask = dma_set_mask_and_switch;
+
+ dma_iommu_ops.set_dma_mask = dma_set_mask_and_switch;
+ set_pci_dma_ops(&dma_iommu_ops);
+
+ printk(KERN_DEBUG "IOMMU fixed mapping established.\n");
+
+ return 0;
+}
+
+static int iommu_fixed_disabled;
+
+static int __init setup_iommu_fixed(char *str)
+{
+ if (strcmp(str, "off") == 0)
+ iommu_fixed_disabled = 1;
+
+ return 1;
+}
+__setup("iommu_fixed=", setup_iommu_fixed);
+
static int __init cell_iommu_init(void)
{
struct device_node *np;
@@ -771,6 +1007,9 @@ static int __init cell_iommu_init(void)
ppc_md.tce_build = tce_build_cell;
ppc_md.tce_free = tce_free_cell;
+ if (!iommu_fixed_disabled && cell_iommu_fixed_mapping_init() == 0)
+ goto bail;
+
/* Create an iommu for each /axon node. */
for_each_node_by_name(np, "axon") {
if (np->parent == NULL || np->parent->parent != NULL)
--
1.5.3.7.1.g4e596e
^ permalink raw reply related
* Re: [PATCH][ppc] logical/bitand typo in powerpc/boot/4xx.c
From: Valentine Barshak @ 2008-01-29 14:22 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev, sr, Roel Kluin, lkml
In-Reply-To: <20080123191704.2d74073a@zod.rchland.ibm.com>
Josh Boyer wrote:
> On Wed, 23 Jan 2008 23:37:33 +0100
> Roel Kluin <12o3l@tiscali.nl> wrote:
>
>> logical/bitand typo
>>
>> Signed-off-by: Roel Kluin <12o3l@tiscali.nl>
>> ---
>> diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c
>> index ebf9e21..dcfb459 100644
>> --- a/arch/powerpc/boot/4xx.c
>> +++ b/arch/powerpc/boot/4xx.c
>> @@ -104,7 +104,7 @@ void ibm4xx_denali_fixup_memsize(void)
>> val = DDR_GET_VAL(val, DDR_CS_MAP, DDR_CS_MAP_SHIFT);
>> cs = 0;
>> while (val) {
>> - if (val && 0x1)
>> + if (val & 0x1)
>> cs++;
>> val = val >> 1;
>> }
>
> Hm, good catch.
Yes, thanks!
Sequoia and Rainier are currently the only boards using denali
controller and have both chipselects enabled (val = 0x3).
In this case the problem doesn't show up and we still get the right cs
value.
Thanks,
Valentine.
>
> Stefan, have you had problems with this code at all?
>
> josh
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ permalink raw reply
* PCI configuration with multiple PCI controllers
From: Laurent Lagrange @ 2008-01-29 14:20 UTC (permalink / raw)
To: linuxppc-dev
Hello,
I have a MPC8641 based board. I try to use the two PCIe controllers. My
firmware configures (physically) the PCI buses as follow:
------------------+
MPC8641 PCIe 1 | bus 1 +--------------+
| --------------> | PCI device 0 |
BUS 0 | +--------------+
- - - - - - - - - +
MPC8641 PCIe 2 | bus 3 +--------------+
| --------------> | PCI device 1 |
BUS 2 | +--------------+
------------------+
I launch the Linux image (2.6.23.9). During the Kernel PCI configuration,
buses behind the 2nd MPC8641 PCIe are skipped because its primary bus don't
start at bus number 0. The kernel reconfigure the primary bus number of the
MPC8641 PCIe 2 controller from 2 to 0.
I can patch the kernel to work with my firmware but I don't know if my PCI
configuration is the good one.
What is the common way to configure the PCI for Linux when a new controller
is found: start the bus number to 0 or to the last bus number + 1?
Regards
^ permalink raw reply
* Re: [PATCH 8/8] Cell IOMMU fixed mapping support
From: Michael Ellerman @ 2008-01-29 15:13 UTC (permalink / raw)
To: Olof Johansson; +Cc: linuxppc-dev, cbe-oss-dev
In-Reply-To: <20080129151511.GA18975@lixom.net>
[-- Attachment #1: Type: text/plain, Size: 1025 bytes --]
On Tue, 2008-01-29 at 09:15 -0600, Olof Johansson wrote:
> On Wed, Jan 30, 2008 at 01:14:03AM +1100, Michael Ellerman wrote:
>
> > For example a machine with 4GB of memory would end up with the normal
> > IOMMU window from 0-2GB and the fixed mapping window from 2GB to 6GB. In
> > this case a 64-bit device wishing to DMA to 1GB would be told to DMA to
> > 3GB, plus any offset required by firmware. The firmware offset is encoded
> > in the "dma-ranges" property.
>
> Shouldn't the fixed mapping be between 4G and 8G (and the offset for 1G
> is at 5G), to account for the MMIO range at 2-4G?
I don't think so, ie. it works setup like that, but I'm not entirely
sure why. Presumably the 2-4GB for MMIO is only for cycles heading out
of the CPU.
cheers
--
Michael Ellerman
OzLabs, IBM Australia Development Lab
wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH 8/8] Cell IOMMU fixed mapping support
From: Olof Johansson @ 2008-01-29 15:15 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, cbe-oss-dev
In-Reply-To: <1cbc0deea968ece13756e3c86ec3af0b7586b80b.1201616038.git.michael@ellerman.id.au>
On Wed, Jan 30, 2008 at 01:14:03AM +1100, Michael Ellerman wrote:
> For example a machine with 4GB of memory would end up with the normal
> IOMMU window from 0-2GB and the fixed mapping window from 2GB to 6GB. In
> this case a 64-bit device wishing to DMA to 1GB would be told to DMA to
> 3GB, plus any offset required by firmware. The firmware offset is encoded
> in the "dma-ranges" property.
Shouldn't the fixed mapping be between 4G and 8G (and the offset for 1G
is at 5G), to account for the MMIO range at 2-4G?
-Olof
^ permalink raw reply
* Re: [patch v6 3/4] USB: add Cypress c67x00 OTG controller HCD driver
From: Alan Stern @ 2008-01-29 15:27 UTC (permalink / raw)
To: Peter Korsgaard; +Cc: linuxppc-dev, dbrownell, USB list
In-Reply-To: <20080129123120.113543000@sunsite.dk>
On Tue, 29 Jan 2008, Peter Korsgaard wrote:
> This patch adds HCD support for the Cypress c67x00 family of devices.
> --- /dev/null
> +++ linux-2.6/drivers/usb/c67x00/c67x00-hcd.c
> +int c67x00_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
> +{
> + struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd);
> + unsigned long flags;
> + int rc;
> +
> + spin_lock_irqsave(&c67x00->lock, flags);
> + rc = usb_hcd_check_unlink_urb(hcd, urb, status);
> + if (rc)
> + goto done;
> +
> + c67x00_release_urb(c67x00, urb);
> + usb_hcd_unlink_urb_from_ep(hcd, urb);
> + spin_unlock_irqrestore(&c67x00->lock, flags);
> +
> + usb_hcd_giveback_urb(hcd, urb, status);
This is wrong. usb_hcd_giveback_urb() must be called with local
interrupts disabled.
> +/*
> + * pre: urb != NULL and c67x00 locked, urb unlocked
> + */
> +static inline void
> +c67x00_giveback_urb(struct c67x00_hcd *c67x00, struct urb *urb, int status)
> +{
> + struct c67x00_urb_priv *urbp;
> +
> + if (!urb)
> + return;
Since you have the documented precondition that urb != NULL, and since
this routine is never called in a context where urb could be NULL,
there's no need for this test. Also, I doubt that this routine really
needs to be inline (and besides, the compiler is better at making such
decisions than we are).
> +static void c67x00_sched_done(unsigned long __c67x00)
> +{
> + struct c67x00_hcd *c67x00 = (struct c67x00_hcd *)__c67x00;
> + struct c67x00_urb_priv *urbp, *tmp;
> + struct urb *urb;
> +
> + spin_lock(&c67x00->lock);
> +
> + /* Loop over the done list and give back all the urbs */
> + list_for_each_entry_safe(urbp, tmp, &c67x00->done_list, hep_node) {
> + urb = urbp->urb;
> + c67x00_release_urb(c67x00, urb);
> + if (!usb_hcd_check_unlink_urb(c67x00_hcd_to_hcd(c67x00),
> + urb, urbp->status)) {
The function call above is completely wrong. It is meant to be used only
from within the dequeue method.
> + usb_hcd_unlink_urb_from_ep(c67x00_hcd_to_hcd(c67x00),
> + urb);
> + spin_unlock(&c67x00->lock);
> + usb_hcd_giveback_urb(c67x00_hcd_to_hcd(c67x00), urb,
> + urbp->status);
> + spin_lock(&c67x00->lock);
> + }
> + }
> + spin_unlock(&c67x00->lock);
> +}
Is there some reason this routine needs to run in a tasklet? Why not
just call it directly?
Also, the fact that it is in a tasklet means that it runs with
interrupts enabled. Hence your spin_lock() and spin_unlock() calls
will not do the right thing.
Alan Stern
^ permalink raw reply
* Re: [PATCH 8/8] Cell IOMMU fixed mapping support
From: Olof Johansson @ 2008-01-29 15:50 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, cbe-oss-dev
In-Reply-To: <1201619625.10012.19.camel@concordia>
On Wed, Jan 30, 2008 at 02:13:45AM +1100, Michael Ellerman wrote:
> On Tue, 2008-01-29 at 09:15 -0600, Olof Johansson wrote:
> > On Wed, Jan 30, 2008 at 01:14:03AM +1100, Michael Ellerman wrote:
> >
> > > For example a machine with 4GB of memory would end up with the normal
> > > IOMMU window from 0-2GB and the fixed mapping window from 2GB to 6GB. In
> > > this case a 64-bit device wishing to DMA to 1GB would be told to DMA to
> > > 3GB, plus any offset required by firmware. The firmware offset is encoded
> > > in the "dma-ranges" property.
> >
> > Shouldn't the fixed mapping be between 4G and 8G (and the offset for 1G
> > is at 5G), to account for the MMIO range at 2-4G?
>
> I don't think so, ie. it works setup like that, but I'm not entirely
> sure why. Presumably the 2-4GB for MMIO is only for cycles heading out
> of the CPU.
Ben denied that being so yesterday. :-)
If that's the case, then you can stick the dynamic range there for >32GB
configs, since it's still addressable with 32 bits.
-Olof
^ permalink raw reply
* Patches for Peak CAN driver for MPC5200B?
From: Mattias Boström @ 2008-01-29 16:48 UTC (permalink / raw)
To: linuxppc-embedded
Hi,
We are using peak-linux-driver-3.17 with patches from DENX (mpc5200)
and Freescale (mpc5200-platform_driver) on a MPC5200B. We have
problems with rmmod, resulting in kernel panic. We also have a problem
with not detecting BusOff. Does anyone know of additional patches that
solve these problems?
If we solve it ourselfs, would this be a good place to post patches?
Regards,
Mattias
^ permalink raw reply
* Re: PATCH[1/1] 8xx: Add clock-frequency to .dts brg entries
From: Scott Wood @ 2008-01-29 16:26 UTC (permalink / raw)
To: Bryan O'Donoghue; +Cc: linuxppc-dev
In-Reply-To: <1201564520.3912.29.camel@neuromancer.mindspace>
On Mon, Jan 28, 2008 at 11:55:20PM +0000, Bryan O'Donoghue wrote:
> You mean that arch/powerpc/boot/mpc8xx.c mpc8xx_set_clocks is supposed
> to be adding this field ?
Yes. Or u-boot, if you're not using the bootwrapper/cuImage.
> I see arch/powerpc/boot/wrapper.a has a reference to the function but -
> and this time I've checked all documentation - there's no mention of how
> to use this library at all... it _looks_ to me like this isn't being
> linked in any way.
>
> It for sure is nowhere in the uImage - and I've taken the preferred
> route of making a uImage with .dtb - genreated from adder875-uboot.dts
In that case, u-boot needs to add that property.
> dtc -O -o adder875-uboot.dtb arch/powerpc/boot/dts/adder875-uboot.dtb
You'll want to use the -p option to add some extra space for u-boot to
use.
> cpm_uart depends on "fsl,cpm-brg" and a field called "clock-frequency"
>
> as I understand it that's
>
> fsl,cpm-brg
> |_clock-frequency
>
> whereas mpc8xx_set_clocks seems to add
>
> /soc/cpm/brg
> |_clock-frequency
The fsl,cpm-brg refers to the compatible property, not the node name.
> mpc866ads.dts - also has a "fsl,cpm-brg" => clock-frequency entry in
>
> linux/arch/powerpc/boot/dts/mpc866ads.dts - and to me this looks like
> the correct approach for get_brgfreq to function properly...
And it's zero, meaning that you still need u-boot or the bootwrapper to
fill in the correct value. The only difference is whether there's a
placeholder property -- they used to be required by older u-boots, but
are no longer necessary.
-Scott
^ permalink raw reply
* Configuring Freecale ucc_geth without a PHY
From: Steven Hein @ 2008-01-29 17:08 UTC (permalink / raw)
To: linuxppc-embedded
Hi all,
I have a custom board with an MPC8358 (our board is based
off of the MPC8360E-MDS development board) that has its eth's
directly connected (GMII) to a Broadcom network switch
part on the same board, with no PHYs between them.
We've have been using a 2.6.16.18 kernel (from TimeSys) up
until now, and I hacked in some crude support for no-phy
configs forced to 100Mbit and 1Gbit speeds. Now I'm
moving to 2.6.22 (with 8360 the patches from bitshrine.org),
and I'm trying to understand how I should do this with
device trees, the new PHY infrastructure, etc. Has anyone
else needed this support? Does anyone have any suggestions
as to how to tackle it?
Thanks,
Steve
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Steve Hein (ssh@sgi.com) Engineering Diagnostics/Software
Silicon Graphics, Inc.
1168 Industrial Blvd. Phone: (715) 726-8410
Chippewa Falls, WI 54729 Fax: (715) 726-6715
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^ permalink raw reply
* Re: Configuring Freecale ucc_geth without a PHY
From: Kim Phillips @ 2008-01-29 17:43 UTC (permalink / raw)
To: Steven Hein; +Cc: linuxppc-embedded
In-Reply-To: <479F5D9B.8040403@sgi.com>
On Tue, 29 Jan 2008 11:08:43 -0600
Steven Hein <ssh@sgi.com> wrote:
> Hi all,
>
> I have a custom board with an MPC8358 (our board is based
> off of the MPC8360E-MDS development board) that has its eth's
> directly connected (GMII) to a Broadcom network switch
> part on the same board, with no PHYs between them.
> We've have been using a 2.6.16.18 kernel (from TimeSys) up
> until now, and I hacked in some crude support for no-phy
> configs forced to 100Mbit and 1Gbit speeds. Now I'm
> moving to 2.6.22 (with 8360 the patches from bitshrine.org),
> and I'm trying to understand how I should do this with
> device trees, the new PHY infrastructure, etc. Has anyone
> else needed this support? Does anyone have any suggestions
> as to how to tackle it?
check out the "fixed-link" property and associated code. This
implementation came about after 2.6.22 though (it's commit-ish
v2.6.23-10096-ga21e282).
Kim
^ permalink raw reply
* Re: [PATCH 0/3] 82xx: MGCOGE support
From: Scott Wood @ 2008-01-29 19:09 UTC (permalink / raw)
To: Heiko Schocher; +Cc: linuxppc-dev
In-Reply-To: <479EFDE8.1030204@denx.de>
On Tue, Jan 29, 2008 at 11:20:24AM +0100, Heiko Schocher wrote:
> the following 4 patches adding support for the MPC8247
> based board MGCOGE from keymile.
Please use descriptive subject lines, rather than the same one for each
patch in the series.
Also, the first three patches could be combined into one.
-Scott
^ permalink raw reply
* Re: Patches for Peak CAN driver for MPC5200B?
From: Grant Likely @ 2008-01-29 19:17 UTC (permalink / raw)
To: Mattias Boström; +Cc: linuxppc-embedded
In-Reply-To: <10d674cb0801290848p8cd6d1xdf03e793e6de58a1@mail.gmail.com>
On 1/29/08, Mattias Bostr=F6m <mattias.bostroem@gmail.com> wrote:
> Hi,
>
> We are using peak-linux-driver-3.17 with patches from DENX (mpc5200)
> and Freescale (mpc5200-platform_driver) on a MPC5200B. We have
> problems with rmmod, resulting in kernel panic. We also have a problem
> with not detecting BusOff. Does anyone know of additional patches that
> solve these problems?
> If we solve it ourselfs, would this be a good place to post patches?
Direct your patches to linuxppc-dev@ozlabs.org. That list gets more reader=
ship.
cc me on any patches that you send to make sure that I see them.
Cheers,
g.
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: [PATCH 3/4] 82xx: MGCOGE support
From: Scott Wood @ 2008-01-29 19:20 UTC (permalink / raw)
To: Heiko Schocher; +Cc: linuxppc-dev
In-Reply-To: <479EFE71.5090201@denx.de>
On Tue, Jan 29, 2008 at 11:22:41AM +0100, Heiko Schocher wrote:
> + model = "MGCOGE";
> + compatible = "fsl,mgcoge";
keymile,mgcoge
> + PowerPC,8247@0 {
[snip]
> + compatible = "fsl,mpc8248-localbus",
All of these 8248s should be 8247.
> + // Temporary -- will go away once kernel uses ranges for get_immrbase().
> + reg = <0xf0000000 0x00053000>;
The patch to use ranges for get_immrbase() just went in, so we can drop this
now.
> + data@0 {
> + compatible = "fsl,cpm-muram-data";
> + reg = <0 0x1100 0x1140
> + 0xec0 0x9800 0x800>;
This doesn't look right. You're excluding 0x40 bytes at 0x1100, which is
where planetcore puts SMC1. However, you're using SMC2 -- and I'm guessing
aren't using planetcore, since this isn't an embedded planet board.
If you're using u-boot, this should be:
reg = <0x80 0x1f80 0x9800 0x800>;
> + /* Monitor port/SMC2 */
> + smc2: serial@11a90 {
> + device_type = "serial";
> + compatible = "fsl,mpc8248-smc-uart",
> + "fsl,cpm2-smc-uart";
> + reg = <0x11a90 0x20 0x1100 0x40 0x88fc 4>;
If you're using u-boot, this should be <0x11a90 0x20 0x40 0x40>.
> + current-speed = <0x1c200>;
This should be decimal.
-Scott
^ permalink raw reply
* Re: [PATCH 4/4] 82xx: MGCOGE support
From: Scott Wood @ 2008-01-29 19:24 UTC (permalink / raw)
To: Heiko Schocher; +Cc: linuxppc-dev
In-Reply-To: <479EFE7F.4000104@denx.de>
On Tue, Jan 29, 2008 at 11:22:55AM +0100, Heiko Schocher wrote:
> To get the serial console on the SMC2 working, the
> following patch is needed:
>
> Fixing serial console on a SMC on MPC82xx based
> board and using CONFIG_PPC_CPM_NEW_BINDING
No, what's needed is for the device tree to be correct (see my comments on
that patch).
> + u16 __iomem *pram_base;
> + struct resource res;
> +
> pinfo->flags |= FLAG_SMC;
> pinfo->smcp = mem;
> pinfo->smcup = pram;
> +
> + if (of_address_to_resource(np, 1, &res)) {
> + ret = -ENOMEM;
> + goto out_pram;
> + }
> + pram_base = of_iomap(np, 2);
> + if (!pram_base) {
> + ret = -ENOMEM;
> + goto out_pram;
> + }
> + *pram_base = res.start;
First of all, use out_be32() rather than direct dereferencing.
Secondly, is it possible for things to get messed up if the SMC registers
were set somewhere else by the bootloader, and that area was previously
allocated by Linux for some other purpose, and the SMC updated the parameter
RAM and corrupted that other purpose? Especially if we have early debug
enabled, and thus don't reset the CPM on boot (or worse, are actively using
it prior to register relocation).
-Scott
^ permalink raw reply
* Re: [PATCH 3/4] 82xx: MGCOGE support
From: Jon Loeliger @ 2008-01-29 19:26 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, Heiko Schocher
In-Reply-To: <20080129192033.GB4051@loki.buserror.net>
Scott Wood wrote:
>> + // Temporary -- will go away once kernel uses ranges for get_immrbase().
>> + reg = <0xf0000000 0x00053000>;
>
> The patch to use ranges for get_immrbase() just went in, so we can drop this
> now.
Most excellent.
Time for YARDS -- Yet Another Rounds of DTS Scrubbing.
jdl
^ permalink raw reply
* Re: [PATCH 4/4] 82xx: MGCOGE support
From: Scott Wood @ 2008-01-29 19:31 UTC (permalink / raw)
To: Heiko Schocher; +Cc: linuxppc-dev
In-Reply-To: <20080129192454.GC4051@loki.buserror.net>
On Tue, Jan 29, 2008 at 01:24:54PM -0600, Scott Wood wrote:
> On Tue, Jan 29, 2008 at 11:22:55AM +0100, Heiko Schocher wrote:
> > + *pram_base = res.start;
>
> First of all, use out_be32() rather than direct dereferencing.
Err, I meant out_be16() of course. :-P
-Scott
^ permalink raw reply
* Re: Patches for Peak CAN driver for MPC5200B?
From: Wolfgang Grandegger @ 2008-01-29 19:50 UTC (permalink / raw)
To: Mattias Boström; +Cc: linuxppc-embedded
In-Reply-To: <10d674cb0801290848p8cd6d1xdf03e793e6de58a1@mail.gmail.com>
Hi Mattias,
Mattias Boström wrote:
> Hi,
>
> We are using peak-linux-driver-3.17 with patches from DENX (mpc5200)
> and Freescale (mpc5200-platform_driver) on a MPC5200B. We have
> problems with rmmod, resulting in kernel panic. We also have a problem
> with not detecting BusOff. Does anyone know of additional patches that
> solve these problems?
> If we solve it ourselfs, would this be a good place to post patches?
This driver is not maintained any more. Are you aware of the Socket-CAN
project at BerliOS:
http://developer.berlios.de/projects/socketcan/
http://svn.berlios.de/wsvn/socketcan/trunk/README?op=file&rev=0&sc=0
It also supports the MSCAN driver and the CAN core will be merged into
2.6.25:
https://lists.berlios.de/pipermail/socketcan-core/2007-November/000795.html
Nevertheless, if you report me your problems, I might be able to help
you. And patches are always welcome.
Wolfgang.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox