You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (24 commits) [POWERPC] Convert the cell IOMMU fixed mapping to 16M IOMMU pages [POWERPC] Allow for different IOMMU page sizes in cell IOMMU code [POWERPC] Cell IOMMU: n_pte_pages is in 4K page units, not IOMMU_PAGE_SIZE [POWERPC] Split setup of IOMMU stab and ptab, allocate dynamic/fixed ptabs separately [POWERPC] Move allocation of cell IOMMU pad page [POWERPC] Remove unused pte_offset variable [POWERPC] Use it_offset not pte_offset in cell IOMMU code [POWERPC] Clearup cell IOMMU fixed mapping terminology [POWERPC] enable hardware watchpoints on cell blades [POWERPC] move celleb DABRX definitions [POWERPC] OProfile: enable callgraph support for Cell [POWERPC] spufs: fix use time accounting on SPE-overcommit [POWERPC] spufs: serialize SLB invalidation against SLB loading [POWERPC] spufs: invalidate SLB translation before adding a new entry [POWERPC] spufs: synchronize IRQ when disabling [POWERPC] spufs: fix order of sputrace thread IDs [POWERPC] Xilinx: hwicap cleanup [POWERPC] 4xx: Use correct board info structure in cuboot wrappers [POWERPC] spufs: fix invalid scheduling of forgotten contexts [POWERPC] 44x: add missing define TARGET_4xx and TARGET_440GX to cuboot-taishan ...
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
#include "44x.h"
|
#include "44x.h"
|
||||||
#include "cuboot.h"
|
#include "cuboot.h"
|
||||||
|
|
||||||
|
#define TARGET_4xx
|
||||||
#define TARGET_44x
|
#define TARGET_44x
|
||||||
#include "ppcboot.h"
|
#include "ppcboot.h"
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "44x.h"
|
#include "44x.h"
|
||||||
#include "cuboot.h"
|
#include "cuboot.h"
|
||||||
|
|
||||||
|
#define TARGET_4xx
|
||||||
#define TARGET_44x
|
#define TARGET_44x
|
||||||
#include "ppcboot.h"
|
#include "ppcboot.h"
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "44x.h"
|
#include "44x.h"
|
||||||
#include "cuboot.h"
|
#include "cuboot.h"
|
||||||
|
|
||||||
|
#define TARGET_4xx
|
||||||
#define TARGET_44x
|
#define TARGET_44x
|
||||||
#include "ppcboot.h"
|
#include "ppcboot.h"
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,9 @@
|
|||||||
#include "dcr.h"
|
#include "dcr.h"
|
||||||
#include "4xx.h"
|
#include "4xx.h"
|
||||||
|
|
||||||
|
#define TARGET_4xx
|
||||||
#define TARGET_44x
|
#define TARGET_44x
|
||||||
|
#define TARGET_440GX
|
||||||
#include "ppcboot.h"
|
#include "ppcboot.h"
|
||||||
|
|
||||||
static bd_t bd;
|
static bd_t bd;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "4xx.h"
|
#include "4xx.h"
|
||||||
#include "cuboot.h"
|
#include "cuboot.h"
|
||||||
|
|
||||||
|
#define TARGET_4xx
|
||||||
#define TARGET_44x
|
#define TARGET_44x
|
||||||
#include "ppcboot.h"
|
#include "ppcboot.h"
|
||||||
|
|
||||||
|
|||||||
@@ -235,7 +235,7 @@
|
|||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <1>;
|
||||||
#size-cells = <2>;
|
#size-cells = <2>;
|
||||||
#address-cells = <3>;
|
#address-cells = <3>;
|
||||||
compatible = "ibm,plb-pciex-405exr", "ibm,plb-pciex";
|
compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex";
|
||||||
primary;
|
primary;
|
||||||
port = <0>; /* port number */
|
port = <0>; /* port number */
|
||||||
reg = <a0000000 20000000 /* Config space access */
|
reg = <a0000000 20000000 /* Config space access */
|
||||||
|
|||||||
@@ -38,8 +38,8 @@
|
|||||||
timebase-frequency = <0>; /* Filled in by zImage */
|
timebase-frequency = <0>; /* Filled in by zImage */
|
||||||
i-cache-line-size = <20>;
|
i-cache-line-size = <20>;
|
||||||
d-cache-line-size = <20>;
|
d-cache-line-size = <20>;
|
||||||
i-cache-size = <20000>;
|
i-cache-size = <8000>;
|
||||||
d-cache-size = <20000>;
|
d-cache-size = <8000>;
|
||||||
dcr-controller;
|
dcr-controller;
|
||||||
dcr-access-method = "native";
|
dcr-access-method = "native";
|
||||||
};
|
};
|
||||||
@@ -136,11 +136,11 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
POB0: opb {
|
POB0: opb {
|
||||||
compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb";
|
compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb";
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
ranges = <00000000 4 e0000000 20000000>;
|
ranges = <00000000 4 e0000000 20000000>;
|
||||||
clock-frequency = <0>; /* Filled in by zImage */
|
clock-frequency = <0>; /* Filled in by zImage */
|
||||||
|
|
||||||
EBC0: ebc {
|
EBC0: ebc {
|
||||||
compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc";
|
compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc";
|
||||||
@@ -153,38 +153,38 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
UART0: serial@10000200 {
|
UART0: serial@10000200 {
|
||||||
device_type = "serial";
|
device_type = "serial";
|
||||||
compatible = "ns16550";
|
compatible = "ns16550";
|
||||||
reg = <10000200 8>;
|
reg = <10000200 8>;
|
||||||
virtual-reg = <a0000200>;
|
virtual-reg = <a0000200>;
|
||||||
clock-frequency = <0>; /* Filled in by zImage */
|
clock-frequency = <0>; /* Filled in by zImage */
|
||||||
current-speed = <1c200>;
|
current-speed = <1c200>;
|
||||||
interrupt-parent = <&UIC0>;
|
interrupt-parent = <&UIC0>;
|
||||||
interrupts = <0 4>;
|
interrupts = <0 4>;
|
||||||
};
|
};
|
||||||
|
|
||||||
UART1: serial@10000300 {
|
UART1: serial@10000300 {
|
||||||
device_type = "serial";
|
device_type = "serial";
|
||||||
compatible = "ns16550";
|
compatible = "ns16550";
|
||||||
reg = <10000300 8>;
|
reg = <10000300 8>;
|
||||||
virtual-reg = <a0000300>;
|
virtual-reg = <a0000300>;
|
||||||
clock-frequency = <0>;
|
clock-frequency = <0>;
|
||||||
current-speed = <0>;
|
current-speed = <0>;
|
||||||
interrupt-parent = <&UIC0>;
|
interrupt-parent = <&UIC0>;
|
||||||
interrupts = <1 4>;
|
interrupts = <1 4>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
UART2: serial@10000600 {
|
UART2: serial@10000600 {
|
||||||
device_type = "serial";
|
device_type = "serial";
|
||||||
compatible = "ns16550";
|
compatible = "ns16550";
|
||||||
reg = <10000600 8>;
|
reg = <10000600 8>;
|
||||||
virtual-reg = <a0000600>;
|
virtual-reg = <a0000600>;
|
||||||
clock-frequency = <0>;
|
clock-frequency = <0>;
|
||||||
current-speed = <0>;
|
current-speed = <0>;
|
||||||
interrupt-parent = <&UIC1>;
|
interrupt-parent = <&UIC1>;
|
||||||
interrupts = <5 4>;
|
interrupts = <5 4>;
|
||||||
};
|
};
|
||||||
|
|
||||||
IIC0: i2c@10000400 {
|
IIC0: i2c@10000400 {
|
||||||
compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
|
compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
|
||||||
|
|||||||
@@ -1151,7 +1151,7 @@ static void cell_handle_interrupt(struct pt_regs *regs,
|
|||||||
for (i = 0; i < num_counters; ++i) {
|
for (i = 0; i < num_counters; ++i) {
|
||||||
if ((interrupt_mask & CBE_PM_CTR_OVERFLOW_INTR(i))
|
if ((interrupt_mask & CBE_PM_CTR_OVERFLOW_INTR(i))
|
||||||
&& ctr[i].enabled) {
|
&& ctr[i].enabled) {
|
||||||
oprofile_add_pc(pc, is_kernel, i);
|
oprofile_add_ext_sample(pc, regs, i, is_kernel);
|
||||||
cbe_write_ctr(cpu, i, reset_value[i]);
|
cbe_write_ctr(cpu, i, reset_value[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -199,6 +199,7 @@ int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(mpc52xx_set_psc_clkdiv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer
|
* mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer
|
||||||
|
|||||||
@@ -113,7 +113,7 @@
|
|||||||
|
|
||||||
/* IOMMU sizing */
|
/* IOMMU sizing */
|
||||||
#define IO_SEGMENT_SHIFT 28
|
#define IO_SEGMENT_SHIFT 28
|
||||||
#define IO_PAGENO_BITS (IO_SEGMENT_SHIFT - IOMMU_PAGE_SHIFT)
|
#define IO_PAGENO_BITS(shift) (IO_SEGMENT_SHIFT - (shift))
|
||||||
|
|
||||||
/* The high bit needs to be set on every DMA address */
|
/* The high bit needs to be set on every DMA address */
|
||||||
#define SPIDER_DMA_OFFSET 0x80000000ul
|
#define SPIDER_DMA_OFFSET 0x80000000ul
|
||||||
@@ -123,7 +123,6 @@ struct iommu_window {
|
|||||||
struct cbe_iommu *iommu;
|
struct cbe_iommu *iommu;
|
||||||
unsigned long offset;
|
unsigned long offset;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
unsigned long pte_offset;
|
|
||||||
unsigned int ioid;
|
unsigned int ioid;
|
||||||
struct iommu_table table;
|
struct iommu_table table;
|
||||||
};
|
};
|
||||||
@@ -200,7 +199,7 @@ static void tce_build_cell(struct iommu_table *tbl, long index, long npages,
|
|||||||
(window->ioid & IOPTE_IOID_Mask);
|
(window->ioid & IOPTE_IOID_Mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset);
|
io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
|
||||||
|
|
||||||
for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE)
|
for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE)
|
||||||
io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
|
io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
|
||||||
@@ -232,7 +231,7 @@ static void tce_free_cell(struct iommu_table *tbl, long index, long npages)
|
|||||||
| (window->ioid & IOPTE_IOID_Mask);
|
| (window->ioid & IOPTE_IOID_Mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset);
|
io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
|
||||||
|
|
||||||
for (i = 0; i < npages; i++)
|
for (i = 0; i < npages; i++)
|
||||||
io_pte[i] = pte;
|
io_pte[i] = pte;
|
||||||
@@ -307,76 +306,84 @@ static int cell_iommu_find_ioc(int nid, unsigned long *base)
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cell_iommu_setup_page_tables(struct cbe_iommu *iommu,
|
static void cell_iommu_setup_stab(struct cbe_iommu *iommu,
|
||||||
unsigned long dbase, unsigned long dsize,
|
unsigned long dbase, unsigned long dsize,
|
||||||
unsigned long fbase, unsigned long fsize)
|
unsigned long fbase, unsigned long fsize)
|
||||||
{
|
{
|
||||||
struct page *page;
|
struct page *page;
|
||||||
int i;
|
unsigned long segments, stab_size;
|
||||||
unsigned long reg, segments, pages_per_segment, ptab_size, stab_size,
|
|
||||||
n_pte_pages, base;
|
|
||||||
|
|
||||||
base = dbase;
|
|
||||||
if (fsize != 0)
|
|
||||||
base = min(fbase, dbase);
|
|
||||||
|
|
||||||
segments = max(dbase + dsize, fbase + fsize) >> IO_SEGMENT_SHIFT;
|
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",
|
pr_debug("%s: iommu[%d]: segments: %lu\n",
|
||||||
__FUNCTION__, iommu->nid, segments, pages_per_segment);
|
__FUNCTION__, iommu->nid, segments);
|
||||||
|
|
||||||
/* set up the segment table */
|
/* set up the segment table */
|
||||||
stab_size = segments * sizeof(unsigned long);
|
stab_size = segments * sizeof(unsigned long);
|
||||||
page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size));
|
page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size));
|
||||||
BUG_ON(!page);
|
BUG_ON(!page);
|
||||||
iommu->stab = page_address(page);
|
iommu->stab = page_address(page);
|
||||||
clear_page(iommu->stab);
|
memset(iommu->stab, 0, stab_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long *cell_iommu_alloc_ptab(struct cbe_iommu *iommu,
|
||||||
|
unsigned long base, unsigned long size, unsigned long gap_base,
|
||||||
|
unsigned long gap_size, unsigned long page_shift)
|
||||||
|
{
|
||||||
|
struct page *page;
|
||||||
|
int i;
|
||||||
|
unsigned long reg, segments, pages_per_segment, ptab_size,
|
||||||
|
n_pte_pages, start_seg, *ptab;
|
||||||
|
|
||||||
|
start_seg = base >> IO_SEGMENT_SHIFT;
|
||||||
|
segments = size >> IO_SEGMENT_SHIFT;
|
||||||
|
pages_per_segment = 1ull << IO_PAGENO_BITS(page_shift);
|
||||||
|
/* PTEs for each segment must start on a 4K bounday */
|
||||||
|
pages_per_segment = max(pages_per_segment,
|
||||||
|
(1 << 12) / sizeof(unsigned long));
|
||||||
|
|
||||||
/* ... and the page tables. Since these are contiguous, we can treat
|
|
||||||
* the page tables as one array of ptes, like pSeries does.
|
|
||||||
*/
|
|
||||||
ptab_size = segments * pages_per_segment * sizeof(unsigned long);
|
ptab_size = segments * pages_per_segment * sizeof(unsigned long);
|
||||||
pr_debug("%s: iommu[%d]: ptab_size: %lu, order: %d\n", __FUNCTION__,
|
pr_debug("%s: iommu[%d]: ptab_size: %lu, order: %d\n", __FUNCTION__,
|
||||||
iommu->nid, ptab_size, get_order(ptab_size));
|
iommu->nid, ptab_size, get_order(ptab_size));
|
||||||
page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(ptab_size));
|
page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(ptab_size));
|
||||||
BUG_ON(!page);
|
BUG_ON(!page);
|
||||||
|
|
||||||
iommu->ptab = page_address(page);
|
ptab = page_address(page);
|
||||||
memset(iommu->ptab, 0, ptab_size);
|
memset(ptab, 0, ptab_size);
|
||||||
|
|
||||||
/* allocate a bogus page for the end of each mapping */
|
/* number of 4K pages needed for a page table */
|
||||||
page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0);
|
n_pte_pages = (pages_per_segment * sizeof(unsigned long)) >> 12;
|
||||||
BUG_ON(!page);
|
|
||||||
iommu->pad_page = page_address(page);
|
|
||||||
clear_page(iommu->pad_page);
|
|
||||||
|
|
||||||
/* number of pages needed for a page table */
|
|
||||||
n_pte_pages = (pages_per_segment *
|
|
||||||
sizeof(unsigned long)) >> IOMMU_PAGE_SHIFT;
|
|
||||||
|
|
||||||
pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n",
|
pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n",
|
||||||
__FUNCTION__, iommu->nid, iommu->stab, iommu->ptab,
|
__FUNCTION__, iommu->nid, iommu->stab, ptab,
|
||||||
n_pte_pages);
|
n_pte_pages);
|
||||||
|
|
||||||
/* initialise the STEs */
|
/* initialise the STEs */
|
||||||
reg = IOSTE_V | ((n_pte_pages - 1) << 5);
|
reg = IOSTE_V | ((n_pte_pages - 1) << 5);
|
||||||
|
|
||||||
if (IOMMU_PAGE_SIZE == 0x1000)
|
switch (page_shift) {
|
||||||
reg |= IOSTE_PS_4K;
|
case 12: reg |= IOSTE_PS_4K; break;
|
||||||
else if (IOMMU_PAGE_SIZE == 0x10000)
|
case 16: reg |= IOSTE_PS_64K; break;
|
||||||
reg |= IOSTE_PS_64K;
|
case 20: reg |= IOSTE_PS_1M; break;
|
||||||
else {
|
case 24: reg |= IOSTE_PS_16M; break;
|
||||||
extern void __unknown_page_size_error(void);
|
default: BUG();
|
||||||
__unknown_page_size_error();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gap_base = gap_base >> IO_SEGMENT_SHIFT;
|
||||||
|
gap_size = gap_size >> IO_SEGMENT_SHIFT;
|
||||||
|
|
||||||
pr_debug("Setting up IOMMU stab:\n");
|
pr_debug("Setting up IOMMU stab:\n");
|
||||||
for (i = base >> IO_SEGMENT_SHIFT; i < segments; i++) {
|
for (i = start_seg; i < (start_seg + segments); i++) {
|
||||||
iommu->stab[i] = reg |
|
if (i >= gap_base && i < (gap_base + gap_size)) {
|
||||||
(__pa(iommu->ptab) + n_pte_pages * IOMMU_PAGE_SIZE * i);
|
pr_debug("\toverlap at %d, skipping\n", i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
iommu->stab[i] = reg | (__pa(ptab) + (n_pte_pages << 12) *
|
||||||
|
(i - start_seg));
|
||||||
pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]);
|
pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ptab;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
|
static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
|
||||||
@@ -423,7 +430,9 @@ static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
|
|||||||
static void cell_iommu_setup_hardware(struct cbe_iommu *iommu,
|
static void cell_iommu_setup_hardware(struct cbe_iommu *iommu,
|
||||||
unsigned long base, unsigned long size)
|
unsigned long base, unsigned long size)
|
||||||
{
|
{
|
||||||
cell_iommu_setup_page_tables(iommu, base, size, 0, 0);
|
cell_iommu_setup_stab(iommu, base, size, 0, 0);
|
||||||
|
iommu->ptab = cell_iommu_alloc_ptab(iommu, base, size, 0, 0,
|
||||||
|
IOMMU_PAGE_SHIFT);
|
||||||
cell_iommu_enable_hardware(iommu);
|
cell_iommu_enable_hardware(iommu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,6 +473,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
|
|||||||
unsigned long pte_offset)
|
unsigned long pte_offset)
|
||||||
{
|
{
|
||||||
struct iommu_window *window;
|
struct iommu_window *window;
|
||||||
|
struct page *page;
|
||||||
u32 ioid;
|
u32 ioid;
|
||||||
|
|
||||||
ioid = cell_iommu_get_ioid(np);
|
ioid = cell_iommu_get_ioid(np);
|
||||||
@@ -475,13 +485,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
|
|||||||
window->size = size;
|
window->size = size;
|
||||||
window->ioid = ioid;
|
window->ioid = ioid;
|
||||||
window->iommu = iommu;
|
window->iommu = iommu;
|
||||||
window->pte_offset = pte_offset;
|
|
||||||
|
|
||||||
window->table.it_blocksize = 16;
|
window->table.it_blocksize = 16;
|
||||||
window->table.it_base = (unsigned long)iommu->ptab;
|
window->table.it_base = (unsigned long)iommu->ptab;
|
||||||
window->table.it_index = iommu->nid;
|
window->table.it_index = iommu->nid;
|
||||||
window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) +
|
window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + pte_offset;
|
||||||
window->pte_offset;
|
|
||||||
window->table.it_size = size >> IOMMU_PAGE_SHIFT;
|
window->table.it_size = size >> IOMMU_PAGE_SHIFT;
|
||||||
|
|
||||||
iommu_init_table(&window->table, iommu->nid);
|
iommu_init_table(&window->table, iommu->nid);
|
||||||
@@ -504,6 +512,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
|
|||||||
* This code also assumes that we have a window that starts at 0,
|
* This code also assumes that we have a window that starts at 0,
|
||||||
* which is the case on all spider based blades.
|
* which is the case on all spider based blades.
|
||||||
*/
|
*/
|
||||||
|
page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0);
|
||||||
|
BUG_ON(!page);
|
||||||
|
iommu->pad_page = page_address(page);
|
||||||
|
clear_page(iommu->pad_page);
|
||||||
|
|
||||||
__set_bit(0, window->table.it_map);
|
__set_bit(0, window->table.it_map);
|
||||||
tce_build_cell(&window->table, window->table.it_offset, 1,
|
tce_build_cell(&window->table, window->table.it_offset, 1,
|
||||||
(unsigned long)iommu->pad_page, DMA_TO_DEVICE);
|
(unsigned long)iommu->pad_page, DMA_TO_DEVICE);
|
||||||
@@ -549,7 +562,7 @@ static void cell_dma_dev_setup_iommu(struct device *dev)
|
|||||||
archdata->dma_data = &window->table;
|
archdata->dma_data = &window->table;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cell_dma_dev_setup_static(struct device *dev);
|
static void cell_dma_dev_setup_fixed(struct device *dev);
|
||||||
|
|
||||||
static void cell_dma_dev_setup(struct device *dev)
|
static void cell_dma_dev_setup(struct device *dev)
|
||||||
{
|
{
|
||||||
@@ -557,7 +570,7 @@ static void cell_dma_dev_setup(struct device *dev)
|
|||||||
|
|
||||||
/* Order is important here, these are not mutually exclusive */
|
/* Order is important here, these are not mutually exclusive */
|
||||||
if (get_dma_ops(dev) == &dma_iommu_fixed_ops)
|
if (get_dma_ops(dev) == &dma_iommu_fixed_ops)
|
||||||
cell_dma_dev_setup_static(dev);
|
cell_dma_dev_setup_fixed(dev);
|
||||||
else if (get_pci_dma_ops() == &dma_iommu_ops)
|
else if (get_pci_dma_ops() == &dma_iommu_ops)
|
||||||
cell_dma_dev_setup_iommu(dev);
|
cell_dma_dev_setup_iommu(dev);
|
||||||
else if (get_pci_dma_ops() == &dma_direct_ops)
|
else if (get_pci_dma_ops() == &dma_direct_ops)
|
||||||
@@ -858,7 +871,7 @@ static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cell_dma_dev_setup_static(struct device *dev)
|
static void cell_dma_dev_setup_fixed(struct device *dev)
|
||||||
{
|
{
|
||||||
struct dev_archdata *archdata = &dev->archdata;
|
struct dev_archdata *archdata = &dev->archdata;
|
||||||
u64 addr;
|
u64 addr;
|
||||||
@@ -869,35 +882,45 @@ static void cell_dma_dev_setup_static(struct device *dev)
|
|||||||
dev_dbg(dev, "iommu: fixed addr = %lx\n", addr);
|
dev_dbg(dev, "iommu: fixed addr = %lx\n", addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void insert_16M_pte(unsigned long addr, unsigned long *ptab,
|
||||||
|
unsigned long base_pte)
|
||||||
|
{
|
||||||
|
unsigned long segment, offset;
|
||||||
|
|
||||||
|
segment = addr >> IO_SEGMENT_SHIFT;
|
||||||
|
offset = (addr >> 24) - (segment << IO_PAGENO_BITS(24));
|
||||||
|
ptab = ptab + (segment * (1 << 12) / sizeof(unsigned long));
|
||||||
|
|
||||||
|
pr_debug("iommu: addr %lx ptab %p segment %lx offset %lx\n",
|
||||||
|
addr, ptab, segment, offset);
|
||||||
|
|
||||||
|
ptab[offset] = base_pte | (__pa(addr) & IOPTE_RPN_Mask);
|
||||||
|
}
|
||||||
|
|
||||||
static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
|
static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
|
||||||
struct device_node *np, unsigned long dbase, unsigned long dsize,
|
struct device_node *np, unsigned long dbase, unsigned long dsize,
|
||||||
unsigned long fbase, unsigned long fsize)
|
unsigned long fbase, unsigned long fsize)
|
||||||
{
|
{
|
||||||
unsigned long base_pte, uaddr, *io_pte;
|
unsigned long base_pte, uaddr, ioaddr, *ptab;
|
||||||
int i;
|
|
||||||
|
ptab = cell_iommu_alloc_ptab(iommu, fbase, fsize, dbase, dsize, 24);
|
||||||
|
|
||||||
dma_iommu_fixed_base = fbase;
|
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);
|
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
|
base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW
|
||||||
| (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask);
|
| (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask);
|
||||||
|
|
||||||
uaddr = 0;
|
for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) {
|
||||||
for (i = fbase; i < fbase + fsize; i++, uaddr += IOMMU_PAGE_SIZE) {
|
|
||||||
/* Don't touch the dynamic region */
|
/* Don't touch the dynamic region */
|
||||||
if (i >= dbase && i < (dbase + dsize)) {
|
ioaddr = uaddr + fbase;
|
||||||
pr_debug("iommu: static/dynamic overlap, skipping\n");
|
if (ioaddr >= dbase && ioaddr < (dbase + dsize)) {
|
||||||
|
pr_debug("iommu: fixed/dynamic overlap, skipping\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
|
|
||||||
|
insert_16M_pte(uaddr, ptab, base_pte);
|
||||||
}
|
}
|
||||||
|
|
||||||
mb();
|
mb();
|
||||||
@@ -995,7 +1018,9 @@ static int __init cell_iommu_fixed_mapping_init(void)
|
|||||||
"fixed window 0x%lx-0x%lx\n", iommu->nid, dbase,
|
"fixed window 0x%lx-0x%lx\n", iommu->nid, dbase,
|
||||||
dbase + dsize, fbase, fbase + fsize);
|
dbase + dsize, fbase, fbase + fsize);
|
||||||
|
|
||||||
cell_iommu_setup_page_tables(iommu, dbase, dsize, fbase, fsize);
|
cell_iommu_setup_stab(iommu, dbase, dsize, fbase, fsize);
|
||||||
|
iommu->ptab = cell_iommu_alloc_ptab(iommu, dbase, dsize, 0, 0,
|
||||||
|
IOMMU_PAGE_SHIFT);
|
||||||
cell_iommu_setup_fixed_ptab(iommu, np, dbase, dsize,
|
cell_iommu_setup_fixed_ptab(iommu, np, dbase, dsize,
|
||||||
fbase, fsize);
|
fbase, fsize);
|
||||||
cell_iommu_enable_hardware(iommu);
|
cell_iommu_enable_hardware(iommu);
|
||||||
|
|||||||
@@ -149,6 +149,11 @@ static void __init cell_init_irq(void)
|
|||||||
mpic_init_IRQ();
|
mpic_init_IRQ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __init cell_set_dabrx(void)
|
||||||
|
{
|
||||||
|
mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER);
|
||||||
|
}
|
||||||
|
|
||||||
static void __init cell_setup_arch(void)
|
static void __init cell_setup_arch(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SPU_BASE
|
#ifdef CONFIG_SPU_BASE
|
||||||
@@ -158,6 +163,8 @@ static void __init cell_setup_arch(void)
|
|||||||
|
|
||||||
cbe_regs_init();
|
cbe_regs_init();
|
||||||
|
|
||||||
|
cell_set_dabrx();
|
||||||
|
|
||||||
#ifdef CONFIG_CBE_RAS
|
#ifdef CONFIG_CBE_RAS
|
||||||
cbe_ras_init();
|
cbe_ras_init();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -81,9 +81,12 @@ struct spu_slb {
|
|||||||
void spu_invalidate_slbs(struct spu *spu)
|
void spu_invalidate_slbs(struct spu *spu)
|
||||||
{
|
{
|
||||||
struct spu_priv2 __iomem *priv2 = spu->priv2;
|
struct spu_priv2 __iomem *priv2 = spu->priv2;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&spu->register_lock, flags);
|
||||||
if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK)
|
if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK)
|
||||||
out_be64(&priv2->slb_invalidate_all_W, 0UL);
|
out_be64(&priv2->slb_invalidate_all_W, 0UL);
|
||||||
|
spin_unlock_irqrestore(&spu->register_lock, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(spu_invalidate_slbs);
|
EXPORT_SYMBOL_GPL(spu_invalidate_slbs);
|
||||||
|
|
||||||
@@ -148,7 +151,11 @@ static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb)
|
|||||||
__func__, slbe, slb->vsid, slb->esid);
|
__func__, slbe, slb->vsid, slb->esid);
|
||||||
|
|
||||||
out_be64(&priv2->slb_index_W, slbe);
|
out_be64(&priv2->slb_index_W, slbe);
|
||||||
|
/* set invalid before writing vsid */
|
||||||
|
out_be64(&priv2->slb_esid_RW, 0);
|
||||||
|
/* now it's safe to write the vsid */
|
||||||
out_be64(&priv2->slb_vsid_RW, slb->vsid);
|
out_be64(&priv2->slb_vsid_RW, slb->vsid);
|
||||||
|
/* setting the new esid makes the entry valid again */
|
||||||
out_be64(&priv2->slb_esid_RW, slb->esid);
|
out_be64(&priv2->slb_esid_RW, slb->esid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,9 +297,11 @@ void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa,
|
|||||||
nr_slbs++;
|
nr_slbs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock_irq(&spu->register_lock);
|
||||||
/* Add the set of SLBs */
|
/* Add the set of SLBs */
|
||||||
for (i = 0; i < nr_slbs; i++)
|
for (i = 0; i < nr_slbs; i++)
|
||||||
spu_load_slb(spu, i, &slbs[i]);
|
spu_load_slb(spu, i, &slbs[i]);
|
||||||
|
spin_unlock_irq(&spu->register_lock);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs);
|
EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs);
|
||||||
|
|
||||||
@@ -337,13 +346,14 @@ spu_irq_class_1(int irq, void *data)
|
|||||||
if (stat & CLASS1_STORAGE_FAULT_INTR)
|
if (stat & CLASS1_STORAGE_FAULT_INTR)
|
||||||
spu_mfc_dsisr_set(spu, 0ul);
|
spu_mfc_dsisr_set(spu, 0ul);
|
||||||
spu_int_stat_clear(spu, 1, stat);
|
spu_int_stat_clear(spu, 1, stat);
|
||||||
spin_unlock(&spu->register_lock);
|
|
||||||
pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat,
|
|
||||||
dar, dsisr);
|
|
||||||
|
|
||||||
if (stat & CLASS1_SEGMENT_FAULT_INTR)
|
if (stat & CLASS1_SEGMENT_FAULT_INTR)
|
||||||
__spu_trap_data_seg(spu, dar);
|
__spu_trap_data_seg(spu, dar);
|
||||||
|
|
||||||
|
spin_unlock(&spu->register_lock);
|
||||||
|
pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat,
|
||||||
|
dar, dsisr);
|
||||||
|
|
||||||
if (stat & CLASS1_STORAGE_FAULT_INTR)
|
if (stat & CLASS1_STORAGE_FAULT_INTR)
|
||||||
__spu_trap_data_map(spu, dar, dsisr);
|
__spu_trap_data_map(spu, dar, dsisr);
|
||||||
|
|
||||||
|
|||||||
@@ -109,13 +109,12 @@ void spu_forget(struct spu_context *ctx)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* This is basically an open-coded spu_acquire_saved, except that
|
* This is basically an open-coded spu_acquire_saved, except that
|
||||||
* we don't acquire the state mutex interruptible.
|
* we don't acquire the state mutex interruptible, and we don't
|
||||||
|
* want this context to be rescheduled on release.
|
||||||
*/
|
*/
|
||||||
mutex_lock(&ctx->state_mutex);
|
mutex_lock(&ctx->state_mutex);
|
||||||
if (ctx->state != SPU_STATE_SAVED) {
|
if (ctx->state != SPU_STATE_SAVED)
|
||||||
set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
|
|
||||||
spu_deactivate(ctx);
|
spu_deactivate(ctx);
|
||||||
}
|
|
||||||
|
|
||||||
mm = ctx->owner;
|
mm = ctx->owner;
|
||||||
ctx->owner = NULL;
|
ctx->owner = NULL;
|
||||||
|
|||||||
@@ -366,6 +366,13 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
|
|||||||
if (offset >= ps_size)
|
if (offset >= ps_size)
|
||||||
return NOPFN_SIGBUS;
|
return NOPFN_SIGBUS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Because we release the mmap_sem, the context may be destroyed while
|
||||||
|
* we're in spu_wait. Grab an extra reference so it isn't destroyed
|
||||||
|
* in the meantime.
|
||||||
|
*/
|
||||||
|
get_spu_context(ctx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have to wait for context to be loaded before we have
|
* We have to wait for context to be loaded before we have
|
||||||
* pages to hand out to the user, but we don't want to wait
|
* pages to hand out to the user, but we don't want to wait
|
||||||
@@ -375,7 +382,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
|
|||||||
* hanged.
|
* hanged.
|
||||||
*/
|
*/
|
||||||
if (spu_acquire(ctx))
|
if (spu_acquire(ctx))
|
||||||
return NOPFN_REFAULT;
|
goto refault;
|
||||||
|
|
||||||
if (ctx->state == SPU_STATE_SAVED) {
|
if (ctx->state == SPU_STATE_SAVED) {
|
||||||
up_read(¤t->mm->mmap_sem);
|
up_read(¤t->mm->mmap_sem);
|
||||||
@@ -391,6 +398,9 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
|
|||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
spu_release(ctx);
|
spu_release(ctx);
|
||||||
|
|
||||||
|
refault:
|
||||||
|
put_spu_context(ctx);
|
||||||
return NOPFN_REFAULT;
|
return NOPFN_REFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
|
|||||||
spu_switch_notify(spu, ctx);
|
spu_switch_notify(spu, ctx);
|
||||||
ctx->state = SPU_STATE_RUNNABLE;
|
ctx->state = SPU_STATE_RUNNABLE;
|
||||||
|
|
||||||
spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED);
|
spuctx_switch_state(ctx, SPU_UTIL_USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -58,12 +58,12 @@ static int sputrace_sprint(char *tbuf, int n)
|
|||||||
ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start));
|
ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start));
|
||||||
|
|
||||||
return snprintf(tbuf, n,
|
return snprintf(tbuf, n,
|
||||||
"[%lu.%09lu] %d: %s (thread = %d, spu = %d)\n",
|
"[%lu.%09lu] %d: %s (ctxthread = %d, spu = %d)\n",
|
||||||
(unsigned long) tv.tv_sec,
|
(unsigned long) tv.tv_sec,
|
||||||
(unsigned long) tv.tv_nsec,
|
(unsigned long) tv.tv_nsec,
|
||||||
t->owner_tid,
|
|
||||||
t->name,
|
|
||||||
t->curr_tid,
|
t->curr_tid,
|
||||||
|
t->name,
|
||||||
|
t->owner_tid,
|
||||||
t->number);
|
t->number);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,6 +188,7 @@ struct spu_probe spu_probes[] = {
|
|||||||
{ "spufs_ps_nopfn__insert", "%p %p", spu_context_event },
|
{ "spufs_ps_nopfn__insert", "%p %p", spu_context_event },
|
||||||
{ "spu_acquire_saved__enter", "%p", spu_context_nospu_event },
|
{ "spu_acquire_saved__enter", "%p", spu_context_nospu_event },
|
||||||
{ "destroy_spu_context__enter", "%p", spu_context_nospu_event },
|
{ "destroy_spu_context__enter", "%p", spu_context_nospu_event },
|
||||||
|
{ "spufs_stop_callback__enter", "%p %p", spu_context_event },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init sputrace_init(void)
|
static int __init sputrace_init(void)
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
|
#include <linux/hardirq.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
@@ -117,6 +118,8 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu)
|
|||||||
* Write INT_MASK_class1 with value of 0.
|
* Write INT_MASK_class1 with value of 0.
|
||||||
* Save INT_Mask_class2 in CSA.
|
* Save INT_Mask_class2 in CSA.
|
||||||
* Write INT_MASK_class2 with value of 0.
|
* Write INT_MASK_class2 with value of 0.
|
||||||
|
* Synchronize all three interrupts to be sure
|
||||||
|
* we no longer execute a handler on another CPU.
|
||||||
*/
|
*/
|
||||||
spin_lock_irq(&spu->register_lock);
|
spin_lock_irq(&spu->register_lock);
|
||||||
if (csa) {
|
if (csa) {
|
||||||
@@ -129,6 +132,9 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu)
|
|||||||
spu_int_mask_set(spu, 2, 0ul);
|
spu_int_mask_set(spu, 2, 0ul);
|
||||||
eieio();
|
eieio();
|
||||||
spin_unlock_irq(&spu->register_lock);
|
spin_unlock_irq(&spu->register_lock);
|
||||||
|
synchronize_irq(spu->irqs[0]);
|
||||||
|
synchronize_irq(spu->irqs[1]);
|
||||||
|
synchronize_irq(spu->irqs[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void set_watchdog_timer(struct spu_state *csa, struct spu *spu)
|
static inline void set_watchdog_timer(struct spu_state *csa, struct spu *spu)
|
||||||
|
|||||||
@@ -21,9 +21,6 @@
|
|||||||
#ifndef _CELLEB_BEAT_H
|
#ifndef _CELLEB_BEAT_H
|
||||||
#define _CELLEB_BEAT_H
|
#define _CELLEB_BEAT_H
|
||||||
|
|
||||||
#define DABRX_KERNEL (1UL<<1)
|
|
||||||
#define DABRX_USER (1UL<<0)
|
|
||||||
|
|
||||||
int64_t beat_get_term_char(uint64_t,uint64_t*,uint64_t*,uint64_t*);
|
int64_t beat_get_term_char(uint64_t,uint64_t*,uint64_t*,uint64_t*);
|
||||||
int64_t beat_put_term_char(uint64_t,uint64_t,uint64_t,uint64_t);
|
int64_t beat_put_term_char(uint64_t,uint64_t,uint64_t,uint64_t);
|
||||||
int64_t beat_repository_encode(int, const char *, uint64_t[4]);
|
int64_t beat_repository_encode(int, const char *, uint64_t[4]);
|
||||||
|
|||||||
@@ -73,8 +73,8 @@
|
|||||||
#define XHI_BUFFER_START 0
|
#define XHI_BUFFER_START 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buffer_icap_get_status: Get the contents of the status register.
|
* buffer_icap_get_status - Get the contents of the status register.
|
||||||
* @parameter base_address: is the base address of the device
|
* @base_address: is the base address of the device
|
||||||
*
|
*
|
||||||
* The status register contains the ICAP status and the done bit.
|
* The status register contains the ICAP status and the done bit.
|
||||||
*
|
*
|
||||||
@@ -94,9 +94,9 @@ static inline u32 buffer_icap_get_status(void __iomem *base_address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buffer_icap_get_bram: Reads data from the storage buffer bram.
|
* buffer_icap_get_bram - Reads data from the storage buffer bram.
|
||||||
* @parameter base_address: contains the base address of the component.
|
* @base_address: contains the base address of the component.
|
||||||
* @parameter offset: The word offset from which the data should be read.
|
* @offset: The word offset from which the data should be read.
|
||||||
*
|
*
|
||||||
* A bram is used as a configuration memory cache. One frame of data can
|
* A bram is used as a configuration memory cache. One frame of data can
|
||||||
* be stored in this "storage buffer".
|
* be stored in this "storage buffer".
|
||||||
@@ -108,8 +108,8 @@ static inline u32 buffer_icap_get_bram(void __iomem *base_address,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buffer_icap_busy: Return true if the icap device is busy
|
* buffer_icap_busy - Return true if the icap device is busy
|
||||||
* @parameter base_address: is the base address of the device
|
* @base_address: is the base address of the device
|
||||||
*
|
*
|
||||||
* The queries the low order bit of the status register, which
|
* The queries the low order bit of the status register, which
|
||||||
* indicates whether the current configuration or readback operation
|
* indicates whether the current configuration or readback operation
|
||||||
@@ -121,8 +121,8 @@ static inline bool buffer_icap_busy(void __iomem *base_address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buffer_icap_busy: Return true if the icap device is not busy
|
* buffer_icap_busy - Return true if the icap device is not busy
|
||||||
* @parameter base_address: is the base address of the device
|
* @base_address: is the base address of the device
|
||||||
*
|
*
|
||||||
* The queries the low order bit of the status register, which
|
* The queries the low order bit of the status register, which
|
||||||
* indicates whether the current configuration or readback operation
|
* indicates whether the current configuration or readback operation
|
||||||
@@ -134,9 +134,9 @@ static inline bool buffer_icap_done(void __iomem *base_address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buffer_icap_set_size: Set the size register.
|
* buffer_icap_set_size - Set the size register.
|
||||||
* @parameter base_address: is the base address of the device
|
* @base_address: is the base address of the device
|
||||||
* @parameter data: The size in bytes.
|
* @data: The size in bytes.
|
||||||
*
|
*
|
||||||
* The size register holds the number of 8 bit bytes to transfer between
|
* The size register holds the number of 8 bit bytes to transfer between
|
||||||
* bram and the icap (or icap to bram).
|
* bram and the icap (or icap to bram).
|
||||||
@@ -148,9 +148,9 @@ static inline void buffer_icap_set_size(void __iomem *base_address,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buffer_icap_mSetoffsetReg: Set the bram offset register.
|
* buffer_icap_set_offset - Set the bram offset register.
|
||||||
* @parameter base_address: contains the base address of the device.
|
* @base_address: contains the base address of the device.
|
||||||
* @parameter data: is the value to be written to the data register.
|
* @data: is the value to be written to the data register.
|
||||||
*
|
*
|
||||||
* The bram offset register holds the starting bram address to transfer
|
* The bram offset register holds the starting bram address to transfer
|
||||||
* data from during configuration or write data to during readback.
|
* data from during configuration or write data to during readback.
|
||||||
@@ -162,9 +162,9 @@ static inline void buffer_icap_set_offset(void __iomem *base_address,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buffer_icap_set_rnc: Set the RNC (Readback not Configure) register.
|
* buffer_icap_set_rnc - Set the RNC (Readback not Configure) register.
|
||||||
* @parameter base_address: contains the base address of the device.
|
* @base_address: contains the base address of the device.
|
||||||
* @parameter data: is the value to be written to the data register.
|
* @data: is the value to be written to the data register.
|
||||||
*
|
*
|
||||||
* The RNC register determines the direction of the data transfer. It
|
* The RNC register determines the direction of the data transfer. It
|
||||||
* controls whether a configuration or readback take place. Writing to
|
* controls whether a configuration or readback take place. Writing to
|
||||||
@@ -178,10 +178,10 @@ static inline void buffer_icap_set_rnc(void __iomem *base_address,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buffer_icap_set_bram: Write data to the storage buffer bram.
|
* buffer_icap_set_bram - Write data to the storage buffer bram.
|
||||||
* @parameter base_address: contains the base address of the component.
|
* @base_address: contains the base address of the component.
|
||||||
* @parameter offset: The word offset at which the data should be written.
|
* @offset: The word offset at which the data should be written.
|
||||||
* @parameter data: The value to be written to the bram offset.
|
* @data: The value to be written to the bram offset.
|
||||||
*
|
*
|
||||||
* A bram is used as a configuration memory cache. One frame of data can
|
* A bram is used as a configuration memory cache. One frame of data can
|
||||||
* be stored in this "storage buffer".
|
* be stored in this "storage buffer".
|
||||||
@@ -193,10 +193,10 @@ static inline void buffer_icap_set_bram(void __iomem *base_address,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buffer_icap_device_read: Transfer bytes from ICAP to the storage buffer.
|
* buffer_icap_device_read - Transfer bytes from ICAP to the storage buffer.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
* @parameter offset: The storage buffer start address.
|
* @offset: The storage buffer start address.
|
||||||
* @parameter count: The number of words (32 bit) to read from the
|
* @count: The number of words (32 bit) to read from the
|
||||||
* device (ICAP).
|
* device (ICAP).
|
||||||
**/
|
**/
|
||||||
static int buffer_icap_device_read(struct hwicap_drvdata *drvdata,
|
static int buffer_icap_device_read(struct hwicap_drvdata *drvdata,
|
||||||
@@ -227,10 +227,10 @@ static int buffer_icap_device_read(struct hwicap_drvdata *drvdata,
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buffer_icap_device_write: Transfer bytes from ICAP to the storage buffer.
|
* buffer_icap_device_write - Transfer bytes from ICAP to the storage buffer.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
* @parameter offset: The storage buffer start address.
|
* @offset: The storage buffer start address.
|
||||||
* @parameter count: The number of words (32 bit) to read from the
|
* @count: The number of words (32 bit) to read from the
|
||||||
* device (ICAP).
|
* device (ICAP).
|
||||||
**/
|
**/
|
||||||
static int buffer_icap_device_write(struct hwicap_drvdata *drvdata,
|
static int buffer_icap_device_write(struct hwicap_drvdata *drvdata,
|
||||||
@@ -261,8 +261,8 @@ static int buffer_icap_device_write(struct hwicap_drvdata *drvdata,
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buffer_icap_reset: Reset the logic of the icap device.
|
* buffer_icap_reset - Reset the logic of the icap device.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
*
|
*
|
||||||
* Writing to the status register resets the ICAP logic in an internal
|
* Writing to the status register resets the ICAP logic in an internal
|
||||||
* version of the core. For the version of the core published in EDK,
|
* version of the core. For the version of the core published in EDK,
|
||||||
@@ -274,10 +274,10 @@ void buffer_icap_reset(struct hwicap_drvdata *drvdata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buffer_icap_set_configuration: Load a partial bitstream from system memory.
|
* buffer_icap_set_configuration - Load a partial bitstream from system memory.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
* @parameter data: Kernel address of the partial bitstream.
|
* @data: Kernel address of the partial bitstream.
|
||||||
* @parameter size: the size of the partial bitstream in 32 bit words.
|
* @size: the size of the partial bitstream in 32 bit words.
|
||||||
**/
|
**/
|
||||||
int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
|
int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
|
||||||
u32 size)
|
u32 size)
|
||||||
@@ -333,10 +333,10 @@ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buffer_icap_get_configuration: Read configuration data from the device.
|
* buffer_icap_get_configuration - Read configuration data from the device.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
* @parameter data: Address of the data representing the partial bitstream
|
* @data: Address of the data representing the partial bitstream
|
||||||
* @parameter size: the size of the partial bitstream in 32 bit words.
|
* @size: the size of the partial bitstream in 32 bit words.
|
||||||
**/
|
**/
|
||||||
int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data,
|
int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data,
|
||||||
u32 size)
|
u32 size)
|
||||||
|
|||||||
@@ -94,9 +94,9 @@
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fifo_icap_fifo_write: Write data to the write FIFO.
|
* fifo_icap_fifo_write - Write data to the write FIFO.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
* @parameter data: the 32-bit value to be written to the FIFO.
|
* @data: the 32-bit value to be written to the FIFO.
|
||||||
*
|
*
|
||||||
* This function will silently fail if the fifo is full.
|
* This function will silently fail if the fifo is full.
|
||||||
**/
|
**/
|
||||||
@@ -108,8 +108,8 @@ static inline void fifo_icap_fifo_write(struct hwicap_drvdata *drvdata,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fifo_icap_fifo_read: Read data from the Read FIFO.
|
* fifo_icap_fifo_read - Read data from the Read FIFO.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
*
|
*
|
||||||
* This function will silently fail if the fifo is empty.
|
* This function will silently fail if the fifo is empty.
|
||||||
**/
|
**/
|
||||||
@@ -121,9 +121,9 @@ static inline u32 fifo_icap_fifo_read(struct hwicap_drvdata *drvdata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fifo_icap_set_read_size: Set the the size register.
|
* fifo_icap_set_read_size - Set the the size register.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
* @parameter data: the size of the following read transaction, in words.
|
* @data: the size of the following read transaction, in words.
|
||||||
**/
|
**/
|
||||||
static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata,
|
static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata,
|
||||||
u32 data)
|
u32 data)
|
||||||
@@ -132,8 +132,8 @@ static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fifo_icap_start_config: Initiate a configuration (write) to the device.
|
* fifo_icap_start_config - Initiate a configuration (write) to the device.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
**/
|
**/
|
||||||
static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata)
|
static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata)
|
||||||
{
|
{
|
||||||
@@ -142,8 +142,8 @@ static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fifo_icap_start_readback: Initiate a readback from the device.
|
* fifo_icap_start_readback - Initiate a readback from the device.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
**/
|
**/
|
||||||
static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata)
|
static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata)
|
||||||
{
|
{
|
||||||
@@ -152,8 +152,8 @@ static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fifo_icap_busy: Return true if the ICAP is still processing a transaction.
|
* fifo_icap_busy - Return true if the ICAP is still processing a transaction.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
**/
|
**/
|
||||||
static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)
|
static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)
|
||||||
{
|
{
|
||||||
@@ -163,8 +163,8 @@ static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fifo_icap_write_fifo_vacancy: Query the write fifo available space.
|
* fifo_icap_write_fifo_vacancy - Query the write fifo available space.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
*
|
*
|
||||||
* Return the number of words that can be safely pushed into the write fifo.
|
* Return the number of words that can be safely pushed into the write fifo.
|
||||||
**/
|
**/
|
||||||
@@ -175,8 +175,8 @@ static inline u32 fifo_icap_write_fifo_vacancy(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fifo_icap_read_fifo_occupancy: Query the read fifo available data.
|
* fifo_icap_read_fifo_occupancy - Query the read fifo available data.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
*
|
*
|
||||||
* Return the number of words that can be safely read from the read fifo.
|
* Return the number of words that can be safely read from the read fifo.
|
||||||
**/
|
**/
|
||||||
@@ -187,11 +187,11 @@ static inline u32 fifo_icap_read_fifo_occupancy(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fifo_icap_set_configuration: Send configuration data to the ICAP.
|
* fifo_icap_set_configuration - Send configuration data to the ICAP.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
* @parameter frame_buffer: a pointer to the data to be written to the
|
* @frame_buffer: a pointer to the data to be written to the
|
||||||
* ICAP device.
|
* ICAP device.
|
||||||
* @parameter num_words: the number of words (32 bit) to write to the ICAP
|
* @num_words: the number of words (32 bit) to write to the ICAP
|
||||||
* device.
|
* device.
|
||||||
|
|
||||||
* This function writes the given user data to the Write FIFO in
|
* This function writes the given user data to the Write FIFO in
|
||||||
@@ -266,10 +266,10 @@ int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fifo_icap_get_configuration: Read configuration data from the device.
|
* fifo_icap_get_configuration - Read configuration data from the device.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
* @parameter data: Address of the data representing the partial bitstream
|
* @data: Address of the data representing the partial bitstream
|
||||||
* @parameter size: the size of the partial bitstream in 32 bit words.
|
* @size: the size of the partial bitstream in 32 bit words.
|
||||||
*
|
*
|
||||||
* This function reads the specified number of words from the ICAP device in
|
* This function reads the specified number of words from the ICAP device in
|
||||||
* the polled mode.
|
* the polled mode.
|
||||||
@@ -335,8 +335,8 @@ int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* buffer_icap_reset: Reset the logic of the icap device.
|
* buffer_icap_reset - Reset the logic of the icap device.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
*
|
*
|
||||||
* This function forces the software reset of the complete HWICAP device.
|
* This function forces the software reset of the complete HWICAP device.
|
||||||
* All the registers will return to the default value and the FIFO is also
|
* All the registers will return to the default value and the FIFO is also
|
||||||
@@ -360,8 +360,8 @@ void fifo_icap_reset(struct hwicap_drvdata *drvdata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fifo_icap_flush_fifo: This function flushes the FIFOs in the device.
|
* fifo_icap_flush_fifo - This function flushes the FIFOs in the device.
|
||||||
* @parameter drvdata: a pointer to the drvdata.
|
* @drvdata: a pointer to the drvdata.
|
||||||
*/
|
*/
|
||||||
void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata)
|
void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata)
|
||||||
{
|
{
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user