Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (144 commits) powerpc/44x: Support 16K/64K base page sizes on 44x powerpc: Force memory size to be a multiple of PAGE_SIZE powerpc/32: Wire up the trampoline code for kdump powerpc/32: Add the ability for a classic ppc kernel to be loaded at 32M powerpc/32: Allow __ioremap on RAM addresses for kdump kernel powerpc/32: Setup OF properties for kdump powerpc/32/kdump: Implement crash_setup_regs() using ppc_save_regs() powerpc: Prepare xmon_save_regs for use with kdump powerpc: Remove default kexec/crash_kernel ops assignments powerpc: Make default kexec/crash_kernel ops implicit powerpc: Setup OF properties for ppc32 kexec powerpc/pseries: Fix cpu hotplug powerpc: Fix KVM build on ppc440 powerpc/cell: add QPACE as a separate Cell platform powerpc/cell: fix build breakage with CONFIG_SPUFS disabled powerpc/mpc5200: fix error paths in PSC UART probe function powerpc/mpc5200: add rts/cts handling in PSC UART driver powerpc/mpc5200: Make PSC UART driver update serial errors counters powerpc/mpc5200: Remove obsolete code from mpc5200 MDIO driver powerpc/mpc5200: Add MDMA/UDMA support to MPC5200 ATA driver ... Fix trivial conflict in drivers/char/Makefile as per Paul's directions
This commit is contained in:
@@ -61,6 +61,9 @@ bcom_ata_init(int queue_len, int maxbufsize)
|
||||
struct bcom_ata_var *var;
|
||||
struct bcom_ata_inc *inc;
|
||||
|
||||
/* Prefetch breaks ATA DMA. Turn it off for ATA DMA */
|
||||
bcom_disable_prefetch();
|
||||
|
||||
tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_ata_bd), 0);
|
||||
if (!tsk)
|
||||
return NULL;
|
||||
|
@@ -16,22 +16,15 @@
|
||||
|
||||
struct bcom_ata_bd {
|
||||
u32 status;
|
||||
u32 dst_pa;
|
||||
u32 src_pa;
|
||||
u32 dst_pa;
|
||||
};
|
||||
|
||||
extern struct bcom_task *
|
||||
bcom_ata_init(int queue_len, int maxbufsize);
|
||||
|
||||
extern void
|
||||
bcom_ata_rx_prepare(struct bcom_task *tsk);
|
||||
|
||||
extern void
|
||||
bcom_ata_tx_prepare(struct bcom_task *tsk);
|
||||
|
||||
extern void
|
||||
bcom_ata_reset_bd(struct bcom_task *tsk);
|
||||
|
||||
extern struct bcom_task * bcom_ata_init(int queue_len, int maxbufsize);
|
||||
extern void bcom_ata_rx_prepare(struct bcom_task *tsk);
|
||||
extern void bcom_ata_tx_prepare(struct bcom_task *tsk);
|
||||
extern void bcom_ata_reset_bd(struct bcom_task *tsk);
|
||||
extern void bcom_ata_release(struct bcom_task *tsk);
|
||||
|
||||
#endif /* __BESTCOMM_ATA_H__ */
|
||||
|
||||
|
@@ -279,7 +279,6 @@ bcom_engine_init(void)
|
||||
int task;
|
||||
phys_addr_t tdt_pa, ctx_pa, var_pa, fdt_pa;
|
||||
unsigned int tdt_size, ctx_size, var_size, fdt_size;
|
||||
u16 regval;
|
||||
|
||||
/* Allocate & clear SRAM zones for FDT, TDTs, contexts and vars/incs */
|
||||
tdt_size = BCOM_MAX_TASKS * sizeof(struct bcom_tdt);
|
||||
@@ -331,10 +330,8 @@ bcom_engine_init(void)
|
||||
out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS);
|
||||
|
||||
/* Disable COMM Bus Prefetch on the original 5200; it's broken */
|
||||
if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR) {
|
||||
regval = in_be16(&bcom_eng->regs->PtdCntrl);
|
||||
out_be16(&bcom_eng->regs->PtdCntrl, regval | 1);
|
||||
}
|
||||
if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR)
|
||||
bcom_disable_prefetch();
|
||||
|
||||
/* Init lock */
|
||||
spin_lock_init(&bcom_eng->lock);
|
||||
|
@@ -16,8 +16,19 @@
|
||||
#ifndef __BESTCOMM_H__
|
||||
#define __BESTCOMM_H__
|
||||
|
||||
struct bcom_bd; /* defined later on ... */
|
||||
|
||||
/**
|
||||
* struct bcom_bd - Structure describing a generic BestComm buffer descriptor
|
||||
* @status: The current status of this buffer. Exact meaning depends on the
|
||||
* task type
|
||||
* @data: An array of u32 extra data. Size of array is task dependant.
|
||||
*
|
||||
* Note: Don't dereference a bcom_bd pointer as an array. The size of the
|
||||
* bcom_bd is variable. Use bcom_get_bd() instead.
|
||||
*/
|
||||
struct bcom_bd {
|
||||
u32 status;
|
||||
u32 data[0]; /* variable payload size */
|
||||
};
|
||||
|
||||
/* ======================================================================== */
|
||||
/* Generic task management */
|
||||
@@ -84,17 +95,6 @@ bcom_get_task_irq(struct bcom_task *tsk) {
|
||||
/* BD based tasks helpers */
|
||||
/* ======================================================================== */
|
||||
|
||||
/**
|
||||
* struct bcom_bd - Structure describing a generic BestComm buffer descriptor
|
||||
* @status: The current status of this buffer. Exact meaning depends on the
|
||||
* task type
|
||||
* @data: An array of u32 whose meaning depends on the task type.
|
||||
*/
|
||||
struct bcom_bd {
|
||||
u32 status;
|
||||
u32 data[1]; /* variable, but at least 1 */
|
||||
};
|
||||
|
||||
#define BCOM_BD_READY 0x40000000ul
|
||||
|
||||
/** _bcom_next_index - Get next input index.
|
||||
@@ -139,6 +139,19 @@ bcom_queue_full(struct bcom_task *tsk)
|
||||
return tsk->outdex == _bcom_next_index(tsk);
|
||||
}
|
||||
|
||||
/**
|
||||
* bcom_get_bd - Get a BD from the queue
|
||||
* @tsk: The BestComm task structure
|
||||
* index: Index of the BD to fetch
|
||||
*/
|
||||
static inline struct bcom_bd
|
||||
*bcom_get_bd(struct bcom_task *tsk, unsigned int index)
|
||||
{
|
||||
/* A cast to (void*) so the address can be incremented by the
|
||||
* real size instead of by sizeof(struct bcom_bd) */
|
||||
return ((void *)tsk->bd) + (index * tsk->bd_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* bcom_buffer_done - Checks if a BestComm
|
||||
* @tsk: The BestComm task structure
|
||||
@@ -146,9 +159,12 @@ bcom_queue_full(struct bcom_task *tsk)
|
||||
static inline int
|
||||
bcom_buffer_done(struct bcom_task *tsk)
|
||||
{
|
||||
struct bcom_bd *bd;
|
||||
if (bcom_queue_empty(tsk))
|
||||
return 0;
|
||||
return !(tsk->bd[tsk->outdex].status & BCOM_BD_READY);
|
||||
|
||||
bd = bcom_get_bd(tsk, tsk->outdex);
|
||||
return !(bd->status & BCOM_BD_READY);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,16 +176,21 @@ bcom_buffer_done(struct bcom_task *tsk)
|
||||
static inline struct bcom_bd *
|
||||
bcom_prepare_next_buffer(struct bcom_task *tsk)
|
||||
{
|
||||
tsk->bd[tsk->index].status = 0; /* cleanup last status */
|
||||
return &tsk->bd[tsk->index];
|
||||
struct bcom_bd *bd;
|
||||
|
||||
bd = bcom_get_bd(tsk, tsk->index);
|
||||
bd->status = 0; /* cleanup last status */
|
||||
return bd;
|
||||
}
|
||||
|
||||
static inline void
|
||||
bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie)
|
||||
{
|
||||
struct bcom_bd *bd = bcom_get_bd(tsk, tsk->index);
|
||||
|
||||
tsk->cookie[tsk->index] = cookie;
|
||||
mb(); /* ensure the bd is really up-to-date */
|
||||
tsk->bd[tsk->index].status |= BCOM_BD_READY;
|
||||
bd->status |= BCOM_BD_READY;
|
||||
tsk->index = _bcom_next_index(tsk);
|
||||
if (tsk->flags & BCOM_FLAGS_ENABLE_TASK)
|
||||
bcom_enable(tsk);
|
||||
@@ -179,10 +200,12 @@ static inline void *
|
||||
bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd)
|
||||
{
|
||||
void *cookie = tsk->cookie[tsk->outdex];
|
||||
struct bcom_bd *bd = bcom_get_bd(tsk, tsk->outdex);
|
||||
|
||||
if (p_status)
|
||||
*p_status = tsk->bd[tsk->outdex].status;
|
||||
*p_status = bd->status;
|
||||
if (p_bd)
|
||||
*p_bd = &tsk->bd[tsk->outdex];
|
||||
*p_bd = bd;
|
||||
tsk->outdex = _bcom_next_outdex(tsk);
|
||||
return cookie;
|
||||
}
|
||||
|
@@ -198,8 +198,8 @@ struct bcom_task_header {
|
||||
#define BCOM_IPR_SCTMR_1 2
|
||||
#define BCOM_IPR_FEC_RX 6
|
||||
#define BCOM_IPR_FEC_TX 5
|
||||
#define BCOM_IPR_ATA_RX 4
|
||||
#define BCOM_IPR_ATA_TX 3
|
||||
#define BCOM_IPR_ATA_RX 7
|
||||
#define BCOM_IPR_ATA_TX 7
|
||||
#define BCOM_IPR_SCPCI_RX 2
|
||||
#define BCOM_IPR_SCPCI_TX 2
|
||||
#define BCOM_IPR_PSC3_RX 2
|
||||
@@ -241,6 +241,22 @@ extern void bcom_set_initiator(int task, int initiator);
|
||||
|
||||
#define TASK_ENABLE 0x8000
|
||||
|
||||
/**
|
||||
* bcom_disable_prefetch - Hook to disable bus prefetching
|
||||
*
|
||||
* ATA DMA and the original MPC5200 need this due to silicon bugs. At the
|
||||
* moment disabling prefetch is a one-way street. There is no mechanism
|
||||
* in place to turn prefetch back on after it has been disabled. There is
|
||||
* no reason it couldn't be done, it would just be more complex to implement.
|
||||
*/
|
||||
static inline void bcom_disable_prefetch(void)
|
||||
{
|
||||
u16 regval;
|
||||
|
||||
regval = in_be16(&bcom_eng->regs->PtdCntrl);
|
||||
out_be16(&bcom_eng->regs->PtdCntrl, regval | 1);
|
||||
};
|
||||
|
||||
static inline void
|
||||
bcom_enable_task(int task)
|
||||
{
|
||||
|
@@ -11,14 +11,20 @@
|
||||
|
||||
#include <asm/ppc_asm.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/bug.h>
|
||||
|
||||
#define DCR_ACCESS_PROLOG(table) \
|
||||
cmpli cr0,r3,1024; \
|
||||
rlwinm r3,r3,4,18,27; \
|
||||
lis r5,table@h; \
|
||||
ori r5,r5,table@l; \
|
||||
add r3,r3,r5; \
|
||||
bge- 1f; \
|
||||
mtctr r3; \
|
||||
bctr
|
||||
bctr; \
|
||||
1: trap; \
|
||||
EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0; \
|
||||
blr
|
||||
|
||||
_GLOBAL(__mfdcr)
|
||||
DCR_ACCESS_PROLOG(__mfdcr_table)
|
||||
|
@@ -124,7 +124,8 @@ EXPORT_SYMBOL_GPL(dcr_write_generic);
|
||||
|
||||
#endif /* defined(CONFIG_PPC_DCR_NATIVE) && defined(CONFIG_PPC_DCR_MMIO) */
|
||||
|
||||
unsigned int dcr_resource_start(struct device_node *np, unsigned int index)
|
||||
unsigned int dcr_resource_start(const struct device_node *np,
|
||||
unsigned int index)
|
||||
{
|
||||
unsigned int ds;
|
||||
const u32 *dr = of_get_property(np, "dcr-reg", &ds);
|
||||
@@ -136,7 +137,7 @@ unsigned int dcr_resource_start(struct device_node *np, unsigned int index)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dcr_resource_start);
|
||||
|
||||
unsigned int dcr_resource_len(struct device_node *np, unsigned int index)
|
||||
unsigned int dcr_resource_len(const struct device_node *np, unsigned int index)
|
||||
{
|
||||
unsigned int ds;
|
||||
const u32 *dr = of_get_property(np, "dcr-reg", &ds);
|
||||
|
@@ -187,7 +187,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
|
||||
printk(KERN_WARNING "Can't get bus-range for %s, assume"
|
||||
" bus 0\n", dev->full_name);
|
||||
|
||||
ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
|
||||
ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
|
||||
hose = pcibios_alloc_controller(dev);
|
||||
if (!hose)
|
||||
return -ENOMEM;
|
||||
@@ -300,7 +300,7 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
|
||||
" bus 0\n", dev->full_name);
|
||||
}
|
||||
|
||||
ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
|
||||
ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
|
||||
hose = pcibios_alloc_controller(dev);
|
||||
if (!hose)
|
||||
return -ENOMEM;
|
||||
|
@@ -57,7 +57,7 @@ void __init setup_grackle(struct pci_controller *hose)
|
||||
{
|
||||
setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0);
|
||||
if (machine_is_compatible("PowerMac1,1"))
|
||||
ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
|
||||
ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
|
||||
if (machine_is_compatible("AAPL,PowerBook1998"))
|
||||
grackle_set_loop_snoop(hose, 1);
|
||||
#if 0 /* Disabled for now, HW problems ??? */
|
||||
|
@@ -661,17 +661,6 @@ static inline void mpic_eoi(struct mpic *mpic)
|
||||
(void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static irqreturn_t mpic_ipi_action(int irq, void *data)
|
||||
{
|
||||
long ipi = (long)data;
|
||||
|
||||
smp_message_recv(ipi);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
/*
|
||||
* Linux descriptor level callbacks
|
||||
*/
|
||||
@@ -1548,13 +1537,7 @@ unsigned int mpic_get_mcirq(void)
|
||||
void mpic_request_ipis(void)
|
||||
{
|
||||
struct mpic *mpic = mpic_primary;
|
||||
long i, err;
|
||||
static char *ipi_names[] = {
|
||||
"IPI0 (call function)",
|
||||
"IPI1 (reschedule)",
|
||||
"IPI2 (call function single)",
|
||||
"IPI3 (debugger break)",
|
||||
};
|
||||
int i;
|
||||
BUG_ON(mpic == NULL);
|
||||
|
||||
printk(KERN_INFO "mpic: requesting IPIs ... \n");
|
||||
@@ -1563,17 +1546,10 @@ void mpic_request_ipis(void)
|
||||
unsigned int vipi = irq_create_mapping(mpic->irqhost,
|
||||
mpic->ipi_vecs[0] + i);
|
||||
if (vipi == NO_IRQ) {
|
||||
printk(KERN_ERR "Failed to map IPI %ld\n", i);
|
||||
break;
|
||||
}
|
||||
err = request_irq(vipi, mpic_ipi_action,
|
||||
IRQF_DISABLED|IRQF_PERCPU,
|
||||
ipi_names[i], (void *)i);
|
||||
if (err) {
|
||||
printk(KERN_ERR "Request of irq %d for IPI %ld failed\n",
|
||||
vipi, i);
|
||||
break;
|
||||
printk(KERN_ERR "Failed to map %s\n", smp_ipi_name[i]);
|
||||
continue;
|
||||
}
|
||||
smp_request_message_ipi(vipi, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -194,11 +194,41 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose,
|
||||
* 4xx PCI 2.x part
|
||||
*/
|
||||
|
||||
static int __init ppc4xx_setup_one_pci_PMM(struct pci_controller *hose,
|
||||
void __iomem *reg,
|
||||
u64 plb_addr,
|
||||
u64 pci_addr,
|
||||
u64 size,
|
||||
unsigned int flags,
|
||||
int index)
|
||||
{
|
||||
u32 ma, pcila, pciha;
|
||||
|
||||
if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) ||
|
||||
size < 0x1000 || (plb_addr & (size - 1)) != 0) {
|
||||
printk(KERN_WARNING "%s: Resource out of range\n",
|
||||
hose->dn->full_name);
|
||||
return -1;
|
||||
}
|
||||
ma = (0xffffffffu << ilog2(size)) | 1;
|
||||
if (flags & IORESOURCE_PREFETCH)
|
||||
ma |= 2;
|
||||
|
||||
pciha = RES_TO_U32_HIGH(pci_addr);
|
||||
pcila = RES_TO_U32_LOW(pci_addr);
|
||||
|
||||
writel(plb_addr, reg + PCIL0_PMM0LA + (0x10 * index));
|
||||
writel(pcila, reg + PCIL0_PMM0PCILA + (0x10 * index));
|
||||
writel(pciha, reg + PCIL0_PMM0PCIHA + (0x10 * index));
|
||||
writel(ma, reg + PCIL0_PMM0MA + (0x10 * index));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose,
|
||||
void __iomem *reg)
|
||||
{
|
||||
u32 la, ma, pcila, pciha;
|
||||
int i, j;
|
||||
int i, j, found_isa_hole = 0;
|
||||
|
||||
/* Setup outbound memory windows */
|
||||
for (i = j = 0; i < 3; i++) {
|
||||
@@ -213,28 +243,29 @@ static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose,
|
||||
break;
|
||||
}
|
||||
|
||||
/* Calculate register values */
|
||||
la = res->start;
|
||||
pciha = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset);
|
||||
pcila = RES_TO_U32_LOW(res->start - hose->pci_mem_offset);
|
||||
/* Configure the resource */
|
||||
if (ppc4xx_setup_one_pci_PMM(hose, reg,
|
||||
res->start,
|
||||
res->start - hose->pci_mem_offset,
|
||||
res->end + 1 - res->start,
|
||||
res->flags,
|
||||
j) == 0) {
|
||||
j++;
|
||||
|
||||
ma = res->end + 1 - res->start;
|
||||
if (!is_power_of_2(ma) || ma < 0x1000 || ma > 0xffffffffu) {
|
||||
printk(KERN_WARNING "%s: Resource out of range\n",
|
||||
hose->dn->full_name);
|
||||
continue;
|
||||
/* If the resource PCI address is 0 then we have our
|
||||
* ISA memory hole
|
||||
*/
|
||||
if (res->start == hose->pci_mem_offset)
|
||||
found_isa_hole = 1;
|
||||
}
|
||||
ma = (0xffffffffu << ilog2(ma)) | 0x1;
|
||||
if (res->flags & IORESOURCE_PREFETCH)
|
||||
ma |= 0x2;
|
||||
|
||||
/* Program register values */
|
||||
writel(la, reg + PCIL0_PMM0LA + (0x10 * j));
|
||||
writel(pcila, reg + PCIL0_PMM0PCILA + (0x10 * j));
|
||||
writel(pciha, reg + PCIL0_PMM0PCIHA + (0x10 * j));
|
||||
writel(ma, reg + PCIL0_PMM0MA + (0x10 * j));
|
||||
j++;
|
||||
}
|
||||
|
||||
/* Handle ISA memory hole if not already covered */
|
||||
if (j <= 2 && !found_isa_hole && hose->isa_mem_size)
|
||||
if (ppc4xx_setup_one_pci_PMM(hose, reg, hose->isa_mem_phys, 0,
|
||||
hose->isa_mem_size, 0, j) == 0)
|
||||
printk(KERN_INFO "%s: Legacy ISA memory support enabled\n",
|
||||
hose->dn->full_name);
|
||||
}
|
||||
|
||||
static void __init ppc4xx_configure_pci_PTMs(struct pci_controller *hose,
|
||||
@@ -352,11 +383,52 @@ static void __init ppc4xx_probe_pci_bridge(struct device_node *np)
|
||||
* 4xx PCI-X part
|
||||
*/
|
||||
|
||||
static int __init ppc4xx_setup_one_pcix_POM(struct pci_controller *hose,
|
||||
void __iomem *reg,
|
||||
u64 plb_addr,
|
||||
u64 pci_addr,
|
||||
u64 size,
|
||||
unsigned int flags,
|
||||
int index)
|
||||
{
|
||||
u32 lah, lal, pciah, pcial, sa;
|
||||
|
||||
if (!is_power_of_2(size) || size < 0x1000 ||
|
||||
(plb_addr & (size - 1)) != 0) {
|
||||
printk(KERN_WARNING "%s: Resource out of range\n",
|
||||
hose->dn->full_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Calculate register values */
|
||||
lah = RES_TO_U32_HIGH(plb_addr);
|
||||
lal = RES_TO_U32_LOW(plb_addr);
|
||||
pciah = RES_TO_U32_HIGH(pci_addr);
|
||||
pcial = RES_TO_U32_LOW(pci_addr);
|
||||
sa = (0xffffffffu << ilog2(size)) | 0x1;
|
||||
|
||||
/* Program register values */
|
||||
if (index == 0) {
|
||||
writel(lah, reg + PCIX0_POM0LAH);
|
||||
writel(lal, reg + PCIX0_POM0LAL);
|
||||
writel(pciah, reg + PCIX0_POM0PCIAH);
|
||||
writel(pcial, reg + PCIX0_POM0PCIAL);
|
||||
writel(sa, reg + PCIX0_POM0SA);
|
||||
} else {
|
||||
writel(lah, reg + PCIX0_POM1LAH);
|
||||
writel(lal, reg + PCIX0_POM1LAL);
|
||||
writel(pciah, reg + PCIX0_POM1PCIAH);
|
||||
writel(pcial, reg + PCIX0_POM1PCIAL);
|
||||
writel(sa, reg + PCIX0_POM1SA);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose,
|
||||
void __iomem *reg)
|
||||
{
|
||||
u32 lah, lal, pciah, pcial, sa;
|
||||
int i, j;
|
||||
int i, j, found_isa_hole = 0;
|
||||
|
||||
/* Setup outbound memory windows */
|
||||
for (i = j = 0; i < 3; i++) {
|
||||
@@ -371,36 +443,29 @@ static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose,
|
||||
break;
|
||||
}
|
||||
|
||||
/* Calculate register values */
|
||||
lah = RES_TO_U32_HIGH(res->start);
|
||||
lal = RES_TO_U32_LOW(res->start);
|
||||
pciah = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset);
|
||||
pcial = RES_TO_U32_LOW(res->start - hose->pci_mem_offset);
|
||||
sa = res->end + 1 - res->start;
|
||||
if (!is_power_of_2(sa) || sa < 0x100000 ||
|
||||
sa > 0xffffffffu) {
|
||||
printk(KERN_WARNING "%s: Resource out of range\n",
|
||||
hose->dn->full_name);
|
||||
continue;
|
||||
}
|
||||
sa = (0xffffffffu << ilog2(sa)) | 0x1;
|
||||
/* Configure the resource */
|
||||
if (ppc4xx_setup_one_pcix_POM(hose, reg,
|
||||
res->start,
|
||||
res->start - hose->pci_mem_offset,
|
||||
res->end + 1 - res->start,
|
||||
res->flags,
|
||||
j) == 0) {
|
||||
j++;
|
||||
|
||||
/* Program register values */
|
||||
if (j == 0) {
|
||||
writel(lah, reg + PCIX0_POM0LAH);
|
||||
writel(lal, reg + PCIX0_POM0LAL);
|
||||
writel(pciah, reg + PCIX0_POM0PCIAH);
|
||||
writel(pcial, reg + PCIX0_POM0PCIAL);
|
||||
writel(sa, reg + PCIX0_POM0SA);
|
||||
} else {
|
||||
writel(lah, reg + PCIX0_POM1LAH);
|
||||
writel(lal, reg + PCIX0_POM1LAL);
|
||||
writel(pciah, reg + PCIX0_POM1PCIAH);
|
||||
writel(pcial, reg + PCIX0_POM1PCIAL);
|
||||
writel(sa, reg + PCIX0_POM1SA);
|
||||
/* If the resource PCI address is 0 then we have our
|
||||
* ISA memory hole
|
||||
*/
|
||||
if (res->start == hose->pci_mem_offset)
|
||||
found_isa_hole = 1;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
/* Handle ISA memory hole if not already covered */
|
||||
if (j <= 1 && !found_isa_hole && hose->isa_mem_size)
|
||||
if (ppc4xx_setup_one_pcix_POM(hose, reg, hose->isa_mem_phys, 0,
|
||||
hose->isa_mem_size, 0, j) == 0)
|
||||
printk(KERN_INFO "%s: Legacy ISA memory support enabled\n",
|
||||
hose->dn->full_name);
|
||||
}
|
||||
|
||||
static void __init ppc4xx_configure_pcix_PIMs(struct pci_controller *hose,
|
||||
@@ -1317,12 +1382,72 @@ static struct pci_ops ppc4xx_pciex_pci_ops =
|
||||
.write = ppc4xx_pciex_write_config,
|
||||
};
|
||||
|
||||
static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port,
|
||||
struct pci_controller *hose,
|
||||
void __iomem *mbase,
|
||||
u64 plb_addr,
|
||||
u64 pci_addr,
|
||||
u64 size,
|
||||
unsigned int flags,
|
||||
int index)
|
||||
{
|
||||
u32 lah, lal, pciah, pcial, sa;
|
||||
|
||||
if (!is_power_of_2(size) ||
|
||||
(index < 2 && size < 0x100000) ||
|
||||
(index == 2 && size < 0x100) ||
|
||||
(plb_addr & (size - 1)) != 0) {
|
||||
printk(KERN_WARNING "%s: Resource out of range\n",
|
||||
hose->dn->full_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Calculate register values */
|
||||
lah = RES_TO_U32_HIGH(plb_addr);
|
||||
lal = RES_TO_U32_LOW(plb_addr);
|
||||
pciah = RES_TO_U32_HIGH(pci_addr);
|
||||
pcial = RES_TO_U32_LOW(pci_addr);
|
||||
sa = (0xffffffffu << ilog2(size)) | 0x1;
|
||||
|
||||
/* Program register values */
|
||||
switch (index) {
|
||||
case 0:
|
||||
out_le32(mbase + PECFG_POM0LAH, pciah);
|
||||
out_le32(mbase + PECFG_POM0LAL, pcial);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff);
|
||||
/* Note that 3 here means enabled | single region */
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, sa | 3);
|
||||
break;
|
||||
case 1:
|
||||
out_le32(mbase + PECFG_POM1LAH, pciah);
|
||||
out_le32(mbase + PECFG_POM1LAL, pcial);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff);
|
||||
/* Note that 3 here means enabled | single region */
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, sa | 3);
|
||||
break;
|
||||
case 2:
|
||||
out_le32(mbase + PECFG_POM2LAH, pciah);
|
||||
out_le32(mbase + PECFG_POM2LAL, pcial);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAH, lah);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff);
|
||||
/* Note that 3 here means enabled | IO space !!! */
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, sa | 3);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port,
|
||||
struct pci_controller *hose,
|
||||
void __iomem *mbase)
|
||||
{
|
||||
u32 lah, lal, pciah, pcial, sa;
|
||||
int i, j;
|
||||
int i, j, found_isa_hole = 0;
|
||||
|
||||
/* Setup outbound memory windows */
|
||||
for (i = j = 0; i < 3; i++) {
|
||||
@@ -1337,53 +1462,38 @@ static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port,
|
||||
break;
|
||||
}
|
||||
|
||||
/* Calculate register values */
|
||||
lah = RES_TO_U32_HIGH(res->start);
|
||||
lal = RES_TO_U32_LOW(res->start);
|
||||
pciah = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset);
|
||||
pcial = RES_TO_U32_LOW(res->start - hose->pci_mem_offset);
|
||||
sa = res->end + 1 - res->start;
|
||||
if (!is_power_of_2(sa) || sa < 0x100000 ||
|
||||
sa > 0xffffffffu) {
|
||||
printk(KERN_WARNING "%s: Resource out of range\n",
|
||||
port->node->full_name);
|
||||
continue;
|
||||
}
|
||||
sa = (0xffffffffu << ilog2(sa)) | 0x1;
|
||||
/* Configure the resource */
|
||||
if (ppc4xx_setup_one_pciex_POM(port, hose, mbase,
|
||||
res->start,
|
||||
res->start - hose->pci_mem_offset,
|
||||
res->end + 1 - res->start,
|
||||
res->flags,
|
||||
j) == 0) {
|
||||
j++;
|
||||
|
||||
/* Program register values */
|
||||
switch (j) {
|
||||
case 0:
|
||||
out_le32(mbase + PECFG_POM0LAH, pciah);
|
||||
out_le32(mbase + PECFG_POM0LAL, pcial);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, sa | 3);
|
||||
break;
|
||||
case 1:
|
||||
out_le32(mbase + PECFG_POM1LAH, pciah);
|
||||
out_le32(mbase + PECFG_POM1LAL, pcial);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, sa | 3);
|
||||
break;
|
||||
/* If the resource PCI address is 0 then we have our
|
||||
* ISA memory hole
|
||||
*/
|
||||
if (res->start == hose->pci_mem_offset)
|
||||
found_isa_hole = 1;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
/* Configure IO, always 64K starting at 0 */
|
||||
if (hose->io_resource.flags & IORESOURCE_IO) {
|
||||
lah = RES_TO_U32_HIGH(hose->io_base_phys);
|
||||
lal = RES_TO_U32_LOW(hose->io_base_phys);
|
||||
out_le32(mbase + PECFG_POM2LAH, 0);
|
||||
out_le32(mbase + PECFG_POM2LAL, 0);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAH, lah);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff);
|
||||
dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, 0xffff0000 | 3);
|
||||
}
|
||||
/* Handle ISA memory hole if not already covered */
|
||||
if (j <= 1 && !found_isa_hole && hose->isa_mem_size)
|
||||
if (ppc4xx_setup_one_pciex_POM(port, hose, mbase,
|
||||
hose->isa_mem_phys, 0,
|
||||
hose->isa_mem_size, 0, j) == 0)
|
||||
printk(KERN_INFO "%s: Legacy ISA memory support enabled\n",
|
||||
hose->dn->full_name);
|
||||
|
||||
/* Configure IO, always 64K starting at 0. We hard wire it to 64K !
|
||||
* Note also that it -has- to be region index 2 on this HW
|
||||
*/
|
||||
if (hose->io_resource.flags & IORESOURCE_IO)
|
||||
ppc4xx_setup_one_pciex_POM(port, hose, mbase,
|
||||
hose->io_base_phys, 0,
|
||||
0x10000, IORESOURCE_IO, 2);
|
||||
}
|
||||
|
||||
static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port,
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/bootmem.h>
|
||||
@@ -38,6 +39,8 @@ static void qe_snums_init(void);
|
||||
static int qe_sdma_init(void);
|
||||
|
||||
static DEFINE_SPINLOCK(qe_lock);
|
||||
DEFINE_SPINLOCK(cmxgcr_lock);
|
||||
EXPORT_SYMBOL(cmxgcr_lock);
|
||||
|
||||
/* QE snum state */
|
||||
enum qe_snum_state {
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
@@ -26,9 +27,6 @@
|
||||
#include <asm/qe.h>
|
||||
#include <asm/ucc.h>
|
||||
|
||||
DEFINE_SPINLOCK(cmxgcr_lock);
|
||||
EXPORT_SYMBOL(cmxgcr_lock);
|
||||
|
||||
int ucc_set_qe_mux_mii_mng(unsigned int ucc_num)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
Reference in New Issue
Block a user