* [PATCH 00/10] Netlogic: Fixes and updates for 3.9
@ 2013-01-14 16:11 Jayachandran C
2013-01-14 16:11 ` [PATCH 01/10] MIPS: Netlogic: add XLS6xx to FMN config Jayachandran C
` (9 more replies)
0 siblings, 10 replies; 21+ messages in thread
From: Jayachandran C @ 2013-01-14 16:11 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
Here are the updates and fixes to Netlogic XLR/XLS/XLP platform code
for 3.9. The major changes in the patchset are:
- Update PIC and irq code to optimize EIMR/EIRR register access
in 32-bit kernel.
- Add PIC timer 7 as a clocksource for both XLR and XLP. This is
a better clocksource compared with Cop0 count, and the PIC timer
count register is available to all cores.
- Fix quad-XLP boards boot problem, and add support for PCIe devices
on all the SoCs on quad-XLP boards.
The rest are minor fixes for various issues.
JC.
Jayachandran C (10):
MIPS: Netlogic: add XLS6xx to FMN config
MIPS: Netlogic: Optimize EIMR/EIRR accesses in 32-bit
MIPS: PCI: Byteswap not needed in little-endian mode
MIPS: Netlogic: Split XLP L1 i-cache among threads
MIPS: Netlogic: Use PIC timer as a clocksource
MIPS: PCI: Prevent hang on XLP reg read
MIPS: Netlogic: No hazards needed for XLR/XLS
MIPS: Netlogic: use preset loops per jiffy
MIPS: Netlogic: Fix for quad-XLP boot
MIPS: PCI: Multi-node PCI support for Netlogic XLP
arch/mips/include/asm/hazards.h | 2 +-
arch/mips/include/asm/netlogic/mips-extns.h | 79 +++++++++++++
.../mips/include/asm/netlogic/xlp-hal/cpucontrol.h | 2 +
arch/mips/include/asm/netlogic/xlp-hal/pic.h | 12 +-
arch/mips/include/asm/netlogic/xlr/pic.h | 48 +++++++-
arch/mips/netlogic/common/irq.c | 41 +++----
arch/mips/netlogic/common/smp.c | 8 +-
arch/mips/netlogic/common/smpboot.S | 6 +
arch/mips/netlogic/common/time.c | 56 ++++++++++
arch/mips/netlogic/xlp/wakeup.c | 35 ++++--
arch/mips/netlogic/xlr/fmn-config.c | 2 +
arch/mips/netlogic/xlr/platform.c | 2 +-
arch/mips/netlogic/xlr/setup.c | 2 +-
arch/mips/pci/pci-xlp.c | 116 +++++++++++++-------
14 files changed, 322 insertions(+), 89 deletions(-)
--
1.7.9.5
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 01/10] MIPS: Netlogic: add XLS6xx to FMN config
2013-01-14 16:11 [PATCH 00/10] Netlogic: Fixes and updates for 3.9 Jayachandran C
@ 2013-01-14 16:11 ` Jayachandran C
2013-01-14 16:11 ` [PATCH 02/10] MIPS: Netlogic: Optimize EIMR/EIRR accesses in 32-bit Jayachandran C
` (8 subsequent siblings)
9 siblings, 0 replies; 21+ messages in thread
From: Jayachandran C @ 2013-01-14 16:11 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
Add support for XLS6xx CPUs to the Fast Message Network (FMN)
configuration.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/netlogic/xlr/fmn-config.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/mips/netlogic/xlr/fmn-config.c b/arch/mips/netlogic/xlr/fmn-config.c
index bed2cff..e8071d6 100644
--- a/arch/mips/netlogic/xlr/fmn-config.c
+++ b/arch/mips/netlogic/xlr/fmn-config.c
@@ -216,6 +216,8 @@ void xlr_board_info_setup(void)
case PRID_IMP_NETLOGIC_XLS404B:
case PRID_IMP_NETLOGIC_XLS408B:
case PRID_IMP_NETLOGIC_XLS416B:
+ case PRID_IMP_NETLOGIC_XLS608B:
+ case PRID_IMP_NETLOGIC_XLS616B:
setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0,
FMN_STNID_GMAC0_TX3, 8, 8, 32);
setup_fmn_cc(&gmac[1], FMN_STNID_GMAC1_FR_0,
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 02/10] MIPS: Netlogic: Optimize EIMR/EIRR accesses in 32-bit
2013-01-14 16:11 [PATCH 00/10] Netlogic: Fixes and updates for 3.9 Jayachandran C
2013-01-14 16:11 ` [PATCH 01/10] MIPS: Netlogic: add XLS6xx to FMN config Jayachandran C
@ 2013-01-14 16:11 ` Jayachandran C
2013-01-14 16:11 ` [PATCH 03/10] MIPS: PCI: Byteswap not needed in little-endian mode Jayachandran C
` (7 subsequent siblings)
9 siblings, 0 replies; 21+ messages in thread
From: Jayachandran C @ 2013-01-14 16:11 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
Provide functions ack_c0_eirr(), set_c0_eimr(), clear_c0_eimr()
and read_c0_eirr_and_eimr() that do the EIMR and EIRR operations
and update the interrupt handling code to use these functions.
Also, use the EIMR register functions to mask interrupts in the
irq code.
The 64-bit interrupt request and mask registers (EIRR and EIMR) are
accessed when the interrupts are off, and the common operations are
to set or clear a bit in these registers. Using the 64-bit c0 access
functions for these operations is not optimal in 32-bit, because it
will disable/restore interrupts and split/join the 64-bit value during
each register access.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/include/asm/netlogic/mips-extns.h | 79 +++++++++++++++++++++++++++
arch/mips/netlogic/common/irq.c | 39 +++++--------
arch/mips/netlogic/common/smp.c | 8 ++-
3 files changed, 98 insertions(+), 28 deletions(-)
diff --git a/arch/mips/include/asm/netlogic/mips-extns.h b/arch/mips/include/asm/netlogic/mips-extns.h
index 32ba6d9..cc42965 100644
--- a/arch/mips/include/asm/netlogic/mips-extns.h
+++ b/arch/mips/include/asm/netlogic/mips-extns.h
@@ -68,6 +68,85 @@ do { \
__write_64bit_c0_register($9, 7, (val)); \
} while (0)
+/*
+ * Handling the 64 bit EIMR and EIRR registers in 32-bit mode with
+ * standard functions will be very inefficient. This provides
+ * optimized functions for the normal operations on the registers.
+ *
+ * Call with interrupts disabled.
+ */
+static inline void ack_c0_eirr(int irq)
+{
+ __asm__ __volatile__(
+ ".set push\n\t"
+ ".set mips64\n\t"
+ ".set noat\n\t"
+ "li $1, 1\n\t"
+ "dsllv $1, $1, %0\n\t"
+ "dmtc0 $1, $9, 6\n\t"
+ ".set pop"
+ : : "r" (irq));
+}
+
+static inline void set_c0_eimr(int irq)
+{
+ __asm__ __volatile__(
+ ".set push\n\t"
+ ".set mips64\n\t"
+ ".set noat\n\t"
+ "li $1, 1\n\t"
+ "dsllv %0, $1, %0\n\t"
+ "dmfc0 $1, $9, 7\n\t"
+ "or $1, %0\n\t"
+ "dmtc0 $1, $9, 7\n\t"
+ ".set pop"
+ : "+r" (irq));
+}
+
+static inline void clear_c0_eimr(int irq)
+{
+ __asm__ __volatile__(
+ ".set push\n\t"
+ ".set mips64\n\t"
+ ".set noat\n\t"
+ "li $1, 1\n\t"
+ "dsllv %0, $1, %0\n\t"
+ "dmfc0 $1, $9, 7\n\t"
+ "or $1, %0\n\t"
+ "xor $1, %0\n\t"
+ "dmtc0 $1, $9, 7\n\t"
+ ".set pop"
+ : "+r" (irq));
+}
+
+/*
+ * Read c0 eimr and c0 eirr, do AND of the two values, the result is
+ * the interrupts which are raised and are not masked.
+ */
+static inline uint64_t read_c0_eirr_and_eimr(void)
+{
+ uint64_t val;
+
+#ifdef CONFIG_64BIT
+ val = read_c0_eimr() & read_c0_eirr();
+#else
+ __asm__ __volatile__(
+ ".set push\n\t"
+ ".set mips64\n\t"
+ ".set noat\n\t"
+ "dmfc0 %M0, $9, 6\n\t"
+ "dmfc0 %L0, $9, 7\n\t"
+ "and %M0, %L0\n\t"
+ "dsll %L0, %M0, 32\n\t"
+ "dsra %M0, %M0, 32\n\t"
+ "dsra %L0, %L0, 32\n\t"
+ ".set pop"
+ : "=r" (val));
+#endif
+
+ return val;
+}
+
static inline int hard_smp_processor_id(void)
{
return __read_32bit_c0_register($15, 1) & 0x3ff;
diff --git a/arch/mips/netlogic/common/irq.c b/arch/mips/netlogic/common/irq.c
index 00dcc7a..d42cd1a 100644
--- a/arch/mips/netlogic/common/irq.c
+++ b/arch/mips/netlogic/common/irq.c
@@ -105,21 +105,23 @@ static void xlp_pic_disable(struct irq_data *d)
static void xlp_pic_mask_ack(struct irq_data *d)
{
struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);
- uint64_t mask = 1ull << pd->picirq;
- write_c0_eirr(mask); /* ack by writing EIRR */
+ clear_c0_eimr(pd->picirq);
+ ack_c0_eirr(pd->picirq);
}
static void xlp_pic_unmask(struct irq_data *d)
{
struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);
- if (!pd)
- return;
+ BUG_ON(!pd);
if (pd->extra_ack)
pd->extra_ack(d);
+ /* re-enable the intr on this cpu */
+ set_c0_eimr(pd->picirq);
+
/* Ack is a single write, no need to lock */
nlm_pic_ack(pd->node->picbase, pd->irt);
}
@@ -134,32 +136,17 @@ static struct irq_chip xlp_pic = {
static void cpuintr_disable(struct irq_data *d)
{
- uint64_t eimr;
- uint64_t mask = 1ull << d->irq;
-
- eimr = read_c0_eimr();
- write_c0_eimr(eimr & ~mask);
+ clear_c0_eimr(d->irq);
}
static void cpuintr_enable(struct irq_data *d)
{
- uint64_t eimr;
- uint64_t mask = 1ull << d->irq;
-
- eimr = read_c0_eimr();
- write_c0_eimr(eimr | mask);
+ set_c0_eimr(d->irq);
}
static void cpuintr_ack(struct irq_data *d)
{
- uint64_t mask = 1ull << d->irq;
-
- write_c0_eirr(mask);
-}
-
-static void cpuintr_nop(struct irq_data *d)
-{
- WARN(d->irq >= PIC_IRQ_BASE, "Bad irq %d", d->irq);
+ ack_c0_eirr(d->irq);
}
/*
@@ -170,9 +157,9 @@ struct irq_chip nlm_cpu_intr = {
.name = "XLP-CPU-INTR",
.irq_enable = cpuintr_enable,
.irq_disable = cpuintr_disable,
- .irq_mask = cpuintr_nop,
- .irq_ack = cpuintr_nop,
- .irq_eoi = cpuintr_ack,
+ .irq_mask = cpuintr_disable,
+ .irq_ack = cpuintr_ack,
+ .irq_eoi = cpuintr_enable,
};
static void __init nlm_init_percpu_irqs(void)
@@ -265,7 +252,7 @@ asmlinkage void plat_irq_dispatch(void)
int i, node;
node = nlm_nodeid();
- eirr = read_c0_eirr() & read_c0_eimr();
+ eirr = read_c0_eirr_and_eimr();
i = __ilog2_u64(eirr);
if (i == -1)
diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c
index a080d9e..2bb95dc 100644
--- a/arch/mips/netlogic/common/smp.c
+++ b/arch/mips/netlogic/common/smp.c
@@ -84,15 +84,19 @@ void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action)
/* IRQ_IPI_SMP_FUNCTION Handler */
void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc)
{
- write_c0_eirr(1ull << irq);
+ clear_c0_eimr(irq);
+ ack_c0_eirr(irq);
smp_call_function_interrupt();
+ set_c0_eimr(irq);
}
/* IRQ_IPI_SMP_RESCHEDULE handler */
void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc)
{
- write_c0_eirr(1ull << irq);
+ clear_c0_eimr(irq);
+ ack_c0_eirr(irq);
scheduler_ipi();
+ set_c0_eimr(irq);
}
/*
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 03/10] MIPS: PCI: Byteswap not needed in little-endian mode
2013-01-14 16:11 [PATCH 00/10] Netlogic: Fixes and updates for 3.9 Jayachandran C
2013-01-14 16:11 ` [PATCH 01/10] MIPS: Netlogic: add XLS6xx to FMN config Jayachandran C
2013-01-14 16:11 ` [PATCH 02/10] MIPS: Netlogic: Optimize EIMR/EIRR accesses in 32-bit Jayachandran C
@ 2013-01-14 16:11 ` Jayachandran C
2013-01-14 17:48 ` Sergei Shtylyov
2013-01-15 6:19 ` Jayachandran C
2013-01-14 16:11 ` [PATCH 04/10] MIPS: Netlogic: Split XLP L1 i-cache among threads Jayachandran C
` (6 subsequent siblings)
9 siblings, 2 replies; 21+ messages in thread
From: Jayachandran C @ 2013-01-14 16:11 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
Wrap the xlp_enable_pci_bswap() function and its call with
'#ifdef __BIG_ENDIAN'. On Netlogic XLP, the PCIe initialization code
to setup to byteswap is needed only in big-endian mode.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/pci/pci-xlp.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c
index 140557a..fe435fc 100644
--- a/arch/mips/pci/pci-xlp.c
+++ b/arch/mips/pci/pci-xlp.c
@@ -191,6 +191,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
return 0;
}
+#ifdef __BIG_ENDIAN
static int xlp_enable_pci_bswap(void)
{
uint64_t pciebase, sysbase;
@@ -224,6 +225,7 @@ static int xlp_enable_pci_bswap(void)
}
return 0;
}
+#endif
static int __init pcibios_init(void)
{
@@ -235,7 +237,9 @@ static int __init pcibios_init(void)
ioport_resource.start = 0;
ioport_resource.end = ~0;
+#ifdef __BIG_ENDIAN
xlp_enable_pci_bswap();
+#endif
set_io_port_base(CKSEG1);
nlm_pci_controller.io_map_base = CKSEG1;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 04/10] MIPS: Netlogic: Split XLP L1 i-cache among threads
2013-01-14 16:11 [PATCH 00/10] Netlogic: Fixes and updates for 3.9 Jayachandran C
` (2 preceding siblings ...)
2013-01-14 16:11 ` [PATCH 03/10] MIPS: PCI: Byteswap not needed in little-endian mode Jayachandran C
@ 2013-01-14 16:11 ` Jayachandran C
2013-01-15 18:04 ` Ralf Baechle
2013-01-14 16:11 ` [PATCH 05/10] MIPS: Netlogic: Use PIC timer as a clocksource Jayachandran C
` (5 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Jayachandran C @ 2013-01-14 16:11 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
Since we now use r4k cache code for Netlogic XLP, it is
better to split L1 icache among the active threads, so that
threads won't step on each other while flushing icache.
The L1 dcache is already split among the threads in the core.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
.../mips/include/asm/netlogic/xlp-hal/cpucontrol.h | 2 ++
arch/mips/netlogic/common/smpboot.S | 6 ++++++
2 files changed, 8 insertions(+)
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h b/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h
index 7b63a6b..6d2e58a 100644
--- a/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h
+++ b/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h
@@ -46,6 +46,8 @@
#define CPU_BLOCKID_FPU 9
#define CPU_BLOCKID_MAP 10
+#define ICU_DEFEATURE 0x100
+
#define LSU_DEFEATURE 0x304
#define LSU_DEBUG_ADDR 0x305
#define LSU_DEBUG_DATA0 0x306
diff --git a/arch/mips/netlogic/common/smpboot.S b/arch/mips/netlogic/common/smpboot.S
index a0b7487..d772a87 100644
--- a/arch/mips/netlogic/common/smpboot.S
+++ b/arch/mips/netlogic/common/smpboot.S
@@ -69,6 +69,12 @@
#endif
mtcr t1, t0
+ li t0, ICU_DEFEATURE
+ mfcr t1, t0
+ ori t1, 0x1000 /* Enable Icache partitioning */
+ mtcr t1, t0
+
+
#ifdef XLP_AX_WORKAROUND
li t0, SCHED_DEFEATURE
lui t1, 0x0100 /* Disable BRU accepting ALU ops */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 05/10] MIPS: Netlogic: Use PIC timer as a clocksource
2013-01-14 16:11 [PATCH 00/10] Netlogic: Fixes and updates for 3.9 Jayachandran C
` (3 preceding siblings ...)
2013-01-14 16:11 ` [PATCH 04/10] MIPS: Netlogic: Split XLP L1 i-cache among threads Jayachandran C
@ 2013-01-14 16:11 ` Jayachandran C
2013-01-14 16:11 ` [PATCH 06/10] MIPS: PCI: Prevent hang on XLP reg read Jayachandran C
` (4 subsequent siblings)
9 siblings, 0 replies; 21+ messages in thread
From: Jayachandran C @ 2013-01-14 16:11 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
The XLR/XLS/XLP PIC has a 8 countdown timers which run at the PIC
frequencey. One of these can be used as a clocksource to provide
timestamps that is common across cores. This can be used in place
of the count/compare clocksource which is per-CPU.
On XLR/XLS PIC registers are 32-bit, so we just use the lower 32-bits
of the PIC counter. On XLP, the whole 64-bit can be used.
Provide common macros and functions for PIC timer registers on XLR/XLS
and XLP, and use them to register a PIC clocksource.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/include/asm/netlogic/xlp-hal/pic.h | 12 +++++-
arch/mips/include/asm/netlogic/xlr/pic.h | 48 ++++++++++++++++++++++--
arch/mips/netlogic/common/irq.c | 2 +-
arch/mips/netlogic/common/time.c | 52 ++++++++++++++++++++++++++
arch/mips/netlogic/xlr/platform.c | 2 +-
arch/mips/netlogic/xlr/setup.c | 2 +-
6 files changed, 110 insertions(+), 8 deletions(-)
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/pic.h b/arch/mips/include/asm/netlogic/xlp-hal/pic.h
index b2e53a5..ea6768c 100644
--- a/arch/mips/include/asm/netlogic/xlp-hal/pic.h
+++ b/arch/mips/include/asm/netlogic/xlp-hal/pic.h
@@ -261,6 +261,8 @@
#define PIC_LOCAL_SCHEDULING 1
#define PIC_GLOBAL_SCHEDULING 0
+#define PIC_CLK_HZ 133333333
+
#define nlm_read_pic_reg(b, r) nlm_read_reg64(b, r)
#define nlm_write_pic_reg(b, r, v) nlm_write_reg64(b, r, v)
#define nlm_get_pic_pcibase(node) nlm_pcicfg_base(XLP_IO_PIC_OFFSET(node))
@@ -315,6 +317,12 @@ nlm_pic_read_timer(uint64_t base, int timer)
return nlm_read_pic_reg(base, PIC_TIMER_COUNT(timer));
}
+static inline uint32_t
+nlm_pic_read_timer32(uint64_t base, int timer)
+{
+ return (uint32_t)nlm_read_pic_reg(base, PIC_TIMER_COUNT(timer));
+}
+
static inline void
nlm_pic_write_timer(uint64_t base, int timer, uint64_t value)
{
@@ -376,9 +384,9 @@ nlm_pic_ack(uint64_t base, int irt_num)
}
static inline void
-nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt)
+nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt, int en)
{
- nlm_pic_write_irt_direct(base, irt, 0, 0, 0, irq, hwt);
+ nlm_pic_write_irt_direct(base, irt, en, 0, 0, irq, hwt);
}
int nlm_irq_to_irt(int irq);
diff --git a/arch/mips/include/asm/netlogic/xlr/pic.h b/arch/mips/include/asm/netlogic/xlr/pic.h
index 9a691b1..effa337 100644
--- a/arch/mips/include/asm/netlogic/xlr/pic.h
+++ b/arch/mips/include/asm/netlogic/xlr/pic.h
@@ -35,10 +35,11 @@
#ifndef _ASM_NLM_XLR_PIC_H
#define _ASM_NLM_XLR_PIC_H
-#define PIC_CLKS_PER_SEC 66666666ULL
+#define PIC_CLK_HZ 66666666
/* PIC hardware interrupt numbers */
#define PIC_IRT_WD_INDEX 0
#define PIC_IRT_TIMER_0_INDEX 1
+#define PIC_IRT_TIMER_INDEX(i) ((i) + PIC_IRT_TIMER_0_INDEX)
#define PIC_IRT_TIMER_1_INDEX 2
#define PIC_IRT_TIMER_2_INDEX 3
#define PIC_IRT_TIMER_3_INDEX 4
@@ -99,6 +100,7 @@
/* PIC Registers */
#define PIC_CTRL 0x00
+#define PIC_CTRL_STE 8 /* timer enable start bit */
#define PIC_IPI 0x04
#define PIC_INT_ACK 0x06
@@ -251,12 +253,52 @@ nlm_pic_ack(uint64_t base, int irt)
}
static inline void
-nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt)
+nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt, int en)
{
nlm_write_reg(base, PIC_IRT_0(irt), (1u << hwt));
/* local scheduling, invalid, level by default */
nlm_write_reg(base, PIC_IRT_1(irt),
- (1 << 30) | (1 << 6) | irq);
+ (en << 30) | (1 << 6) | irq);
+}
+
+static inline uint64_t
+nlm_pic_read_timer(uint64_t base, int timer)
+{
+ uint32_t up1, up2, low;
+
+ up1 = nlm_read_reg(base, PIC_TIMER_COUNT_1(timer));
+ low = nlm_read_reg(base, PIC_TIMER_COUNT_0(timer));
+ up2 = nlm_read_reg(base, PIC_TIMER_COUNT_1(timer));
+
+ if (up1 != up2) /* wrapped, get the new low */
+ low = nlm_read_reg(base, PIC_TIMER_COUNT_0(timer));
+ return ((uint64_t)up2 << 32) | low;
+
+}
+
+static inline uint32_t
+nlm_pic_read_timer32(uint64_t base, int timer)
+{
+ return nlm_read_reg(base, PIC_TIMER_COUNT_0(timer));
+}
+
+static inline void
+nlm_pic_set_timer(uint64_t base, int timer, uint64_t value, int irq, int cpu)
+{
+ uint32_t up, low;
+ uint64_t pic_ctrl = nlm_read_reg(base, PIC_CTRL);
+ int en;
+
+ en = (irq > 0);
+ up = value >> 32;
+ low = value & 0xFFFFFFFF;
+ nlm_write_reg(base, PIC_TIMER_MAXVAL_0(timer), low);
+ nlm_write_reg(base, PIC_TIMER_MAXVAL_1(timer), up);
+ nlm_pic_init_irt(base, PIC_IRT_TIMER_INDEX(timer), irq, cpu, 0);
+
+ /* enable the timer */
+ pic_ctrl |= (1 << (PIC_CTRL_STE + timer));
+ nlm_write_reg(base, PIC_CTRL, pic_ctrl);
}
#endif
#endif /* _ASM_NLM_XLR_PIC_H */
diff --git a/arch/mips/netlogic/common/irq.c b/arch/mips/netlogic/common/irq.c
index d42cd1a..642f1e4 100644
--- a/arch/mips/netlogic/common/irq.c
+++ b/arch/mips/netlogic/common/irq.c
@@ -217,7 +217,7 @@ static void nlm_init_node_irqs(int node)
nlm_setup_pic_irq(node, i, i, irt);
/* set interrupts to first cpu in node */
nlm_pic_init_irt(nodep->picbase, irt, i,
- node * NLM_CPUS_PER_NODE);
+ node * NLM_CPUS_PER_NODE, 0);
irqmask |= (1ull << i);
}
nodep->irqmask = irqmask;
diff --git a/arch/mips/netlogic/common/time.c b/arch/mips/netlogic/common/time.c
index bd3e498..20f89bc 100644
--- a/arch/mips/netlogic/common/time.c
+++ b/arch/mips/netlogic/common/time.c
@@ -35,16 +35,68 @@
#include <linux/init.h>
#include <asm/time.h>
+#include <asm/cpu-features.h>
+
#include <asm/netlogic/interrupt.h>
#include <asm/netlogic/common.h>
+#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/common.h>
+
+#if defined(CONFIG_CPU_XLP)
+#include <asm/netlogic/xlp-hal/iomap.h>
+#include <asm/netlogic/xlp-hal/xlp.h>
+#include <asm/netlogic/xlp-hal/pic.h>
+#elif defined(CONFIG_CPU_XLR)
+#include <asm/netlogic/xlr/iomap.h>
+#include <asm/netlogic/xlr/pic.h>
+#include <asm/netlogic/xlr/xlr.h>
+#else
+#error "Unknown CPU"
+#endif
unsigned int __cpuinit get_c0_compare_int(void)
{
return IRQ_TIMER;
}
+static cycle_t nlm_get_pic_timer(struct clocksource *cs)
+{
+ uint64_t picbase = nlm_get_node(0)->picbase;
+
+ return ~nlm_pic_read_timer(picbase, PIC_CLOCK_TIMER);
+}
+
+static cycle_t nlm_get_pic_timer32(struct clocksource *cs)
+{
+ uint64_t picbase = nlm_get_node(0)->picbase;
+
+ return ~nlm_pic_read_timer32(picbase, PIC_CLOCK_TIMER);
+}
+
+static struct clocksource csrc_pic = {
+ .name = "PIC",
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void nlm_init_pic_timer(void)
+{
+ uint64_t picbase = nlm_get_node(0)->picbase;
+
+ nlm_pic_set_timer(picbase, PIC_CLOCK_TIMER, ~0ULL, 0, 0);
+ if (current_cpu_data.cputype == CPU_XLR) {
+ csrc_pic.mask = CLOCKSOURCE_MASK(32);
+ csrc_pic.read = nlm_get_pic_timer32;
+ } else {
+ csrc_pic.mask = CLOCKSOURCE_MASK(64);
+ csrc_pic.read = nlm_get_pic_timer;
+ }
+ csrc_pic.rating = 1000;
+ clocksource_register_hz(&csrc_pic, PIC_CLK_HZ);
+}
+
void __init plat_time_init(void)
{
+ nlm_init_pic_timer();
mips_hpt_frequency = nlm_get_cpu_frequency();
pr_info("MIPS counter frequency [%ld]\n",
(unsigned long)mips_hpt_frequency);
diff --git a/arch/mips/netlogic/xlr/platform.c b/arch/mips/netlogic/xlr/platform.c
index 507230e..ce838f9 100644
--- a/arch/mips/netlogic/xlr/platform.c
+++ b/arch/mips/netlogic/xlr/platform.c
@@ -64,7 +64,7 @@ void nlm_xlr_uart_out(struct uart_port *p, int offset, int value)
.iotype = UPIO_MEM32, \
.flags = (UPF_SKIP_TEST | \
UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\
- .uartclk = PIC_CLKS_PER_SEC, \
+ .uartclk = PIC_CLK_HZ, \
.type = PORT_16550A, \
.serial_in = nlm_xlr_uart_in, \
.serial_out = nlm_xlr_uart_out, \
diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c
index 4e7f49d..f72f92e 100644
--- a/arch/mips/netlogic/xlr/setup.c
+++ b/arch/mips/netlogic/xlr/setup.c
@@ -70,7 +70,7 @@ static void __init nlm_early_serial_setup(void)
s.iotype = UPIO_MEM32;
s.regshift = 2;
s.irq = PIC_UART_0_IRQ;
- s.uartclk = PIC_CLKS_PER_SEC;
+ s.uartclk = PIC_CLK_HZ;
s.serial_in = nlm_xlr_uart_in;
s.serial_out = nlm_xlr_uart_out;
s.mapbase = uart_base;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 06/10] MIPS: PCI: Prevent hang on XLP reg read
2013-01-14 16:11 [PATCH 00/10] Netlogic: Fixes and updates for 3.9 Jayachandran C
` (4 preceding siblings ...)
2013-01-14 16:11 ` [PATCH 05/10] MIPS: Netlogic: Use PIC timer as a clocksource Jayachandran C
@ 2013-01-14 16:11 ` Jayachandran C
2013-01-14 16:11 ` [PATCH 07/10] MIPS: Netlogic: No hazards needed for XLR/XLS Jayachandran C
` (3 subsequent siblings)
9 siblings, 0 replies; 21+ messages in thread
From: Jayachandran C @ 2013-01-14 16:11 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
Reading PCI extended register at 0x255 on a bridge will hang if there
is no device connected on the link. Make PCI read routine skip this
register.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/pci/pci-xlp.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c
index fe435fc..5cd95a0 100644
--- a/arch/mips/pci/pci-xlp.c
+++ b/arch/mips/pci/pci-xlp.c
@@ -64,8 +64,12 @@ static inline u32 pci_cfg_read_32bit(struct pci_bus *bus, unsigned int devfn,
u32 data;
u32 *cfgaddr;
+ where &= ~3;
+ if (bus->number == 0 && PCI_SLOT(devfn) == 1 && where == 0x954)
+ return 0xffffffff;
+
cfgaddr = (u32 *)(pci_config_base +
- pci_cfg_addr(bus->number, devfn, where & ~3));
+ pci_cfg_addr(bus->number, devfn, where));
data = *cfgaddr;
return data;
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 07/10] MIPS: Netlogic: No hazards needed for XLR/XLS
2013-01-14 16:11 [PATCH 00/10] Netlogic: Fixes and updates for 3.9 Jayachandran C
` (5 preceding siblings ...)
2013-01-14 16:11 ` [PATCH 06/10] MIPS: PCI: Prevent hang on XLP reg read Jayachandran C
@ 2013-01-14 16:11 ` Jayachandran C
2013-01-14 16:12 ` [PATCH 08/10] MIPS: Netlogic: use preset loops per jiffy Jayachandran C
` (2 subsequent siblings)
9 siblings, 0 replies; 21+ messages in thread
From: Jayachandran C @ 2013-01-14 16:11 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
TLB and COP0 hazards are handled in hardware for Netlogic XLR/XLS
SoCs. Update hazards.h to pick more optimal set of definitions when
compiling for XLR/XLS.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/include/asm/hazards.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/mips/include/asm/hazards.h b/arch/mips/include/asm/hazards.h
index f0324e9..9c309ae 100644
--- a/arch/mips/include/asm/hazards.h
+++ b/arch/mips/include/asm/hazards.h
@@ -141,7 +141,7 @@ do { \
#elif defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \
defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_CPU_R10000) || \
- defined(CONFIG_CPU_R5500)
+ defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_XLR)
/*
* R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 08/10] MIPS: Netlogic: use preset loops per jiffy
2013-01-14 16:11 [PATCH 00/10] Netlogic: Fixes and updates for 3.9 Jayachandran C
` (6 preceding siblings ...)
2013-01-14 16:11 ` [PATCH 07/10] MIPS: Netlogic: No hazards needed for XLR/XLS Jayachandran C
@ 2013-01-14 16:12 ` Jayachandran C
2013-01-14 16:12 ` [PATCH 09/10] MIPS: Netlogic: Fix for quad-XLP boot Jayachandran C
2013-01-14 16:12 ` [PATCH 10/10] MIPS: PCI: Multi-node PCI support for Netlogic XLP Jayachandran C
9 siblings, 0 replies; 21+ messages in thread
From: Jayachandran C @ 2013-01-14 16:12 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
Doing calibrate delay on a hardware thread will be inaccurate since
it depends on the load on other threads in the core. It will also
slow down the boot process when done for 128 hardware threads. Switch
to a pre-computed loops per jiffy based on the core frequency. The
value is computed based on the core frequency and roughly matches the
value calculated by calibrate_delay().
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/netlogic/common/time.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/mips/netlogic/common/time.c b/arch/mips/netlogic/common/time.c
index 20f89bc..5c56555 100644
--- a/arch/mips/netlogic/common/time.c
+++ b/arch/mips/netlogic/common/time.c
@@ -98,6 +98,10 @@ void __init plat_time_init(void)
{
nlm_init_pic_timer();
mips_hpt_frequency = nlm_get_cpu_frequency();
+ if (current_cpu_type() == CPU_XLR)
+ preset_lpj = mips_hpt_frequency / (3 * HZ);
+ else
+ preset_lpj = mips_hpt_frequency / (2 * HZ);
pr_info("MIPS counter frequency [%ld]\n",
(unsigned long)mips_hpt_frequency);
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 09/10] MIPS: Netlogic: Fix for quad-XLP boot
2013-01-14 16:11 [PATCH 00/10] Netlogic: Fixes and updates for 3.9 Jayachandran C
` (7 preceding siblings ...)
2013-01-14 16:12 ` [PATCH 08/10] MIPS: Netlogic: use preset loops per jiffy Jayachandran C
@ 2013-01-14 16:12 ` Jayachandran C
2013-01-14 16:12 ` [PATCH 10/10] MIPS: PCI: Multi-node PCI support for Netlogic XLP Jayachandran C
9 siblings, 0 replies; 21+ messages in thread
From: Jayachandran C @ 2013-01-14 16:12 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
On multi-chip boards, the first core on slave SoCs may take much
more time to wakeup. Add code to wait for the core to come up before
proceeding with the rest of the boot up.
Update xlp_wakeup_core to also skip the boot node and the boot CPU
initialization which is already complete.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/netlogic/xlp/wakeup.c | 35 +++++++++++++++++++++++++----------
1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c
index cb90106..abb3e08 100644
--- a/arch/mips/netlogic/xlp/wakeup.c
+++ b/arch/mips/netlogic/xlp/wakeup.c
@@ -51,7 +51,7 @@
#include <asm/netlogic/xlp-hal/xlp.h>
#include <asm/netlogic/xlp-hal/sys.h>
-static int xlp_wakeup_core(uint64_t sysbase, int core)
+static int xlp_wakeup_core(uint64_t sysbase, int node, int core)
{
uint32_t coremask, value;
int count;
@@ -82,36 +82,51 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
struct nlm_soc_info *nodep;
uint64_t syspcibase;
uint32_t syscoremask;
- int core, n, cpu;
+ int core, n, cpu, count, val;
for (n = 0; n < NLM_NR_NODES; n++) {
syspcibase = nlm_get_sys_pcibase(n);
if (nlm_read_reg(syspcibase, 0) == 0xffffffff)
break;
- /* read cores in reset from SYS and account for boot cpu */
- nlm_node_init(n);
+ /* read cores in reset from SYS */
+ if (n != 0)
+ nlm_node_init(n);
nodep = nlm_get_node(n);
syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET);
- if (n == 0)
+ /* The boot cpu */
+ if (n == 0) {
syscoremask |= 1;
+ nodep->coremask = 1;
+ }
for (core = 0; core < NLM_CORES_PER_NODE; core++) {
+ /* we will be on node 0 core 0 */
+ if (n == 0 && core == 0)
+ continue;
+
/* see if the core exists */
if ((syscoremask & (1 << core)) == 0)
continue;
- /* see if at least the first thread is enabled */
+ /* see if at least the first hw thread is enabled */
cpu = (n * NLM_CORES_PER_NODE + core)
* NLM_THREADS_PER_CORE;
if (!cpumask_test_cpu(cpu, wakeup_mask))
continue;
/* wake up the core */
- if (xlp_wakeup_core(nodep->sysbase, core))
- nodep->coremask |= 1u << core;
- else
- pr_err("Failed to enable core %d\n", core);
+ if (!xlp_wakeup_core(nodep->sysbase, n, core))
+ continue;
+
+ /* core is up */
+ nodep->coremask |= 1u << core;
+
+ /* spin until the first hw thread sets its ready */
+ count = 0x20000000;
+ do {
+ val = *(volatile int *)&nlm_cpu_ready[cpu];
+ } while (val == 0 && --count > 0);
}
}
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 10/10] MIPS: PCI: Multi-node PCI support for Netlogic XLP
2013-01-14 16:11 [PATCH 00/10] Netlogic: Fixes and updates for 3.9 Jayachandran C
` (8 preceding siblings ...)
2013-01-14 16:12 ` [PATCH 09/10] MIPS: Netlogic: Fix for quad-XLP boot Jayachandran C
@ 2013-01-14 16:12 ` Jayachandran C
2013-01-15 6:20 ` Jayachandran C
2013-01-15 6:38 ` Jayachandran C
9 siblings, 2 replies; 21+ messages in thread
From: Jayachandran C @ 2013-01-14 16:12 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
On a multi-chip XLP board, each node can have 4 PCIe links. Update
XLP PCI code to initialize PCI on all the nodes.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/pci/pci-xlp.c | 106 +++++++++++++++++++++++++++++------------------
1 file changed, 65 insertions(+), 41 deletions(-)
diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c
index 5cd95a0..f6b1c70 100644
--- a/arch/mips/pci/pci-xlp.c
+++ b/arch/mips/pci/pci-xlp.c
@@ -46,6 +46,7 @@
#include <asm/netlogic/interrupt.h>
#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/common.h>
#include <asm/netlogic/xlp-hal/iomap.h>
#include <asm/netlogic/xlp-hal/pic.h>
@@ -161,32 +162,38 @@ struct pci_controller nlm_pci_controller = {
.io_offset = 0x00000000UL,
};
-static int get_irq_vector(const struct pci_dev *dev)
+static struct pci_dev *xlp_get_pcie_link(const struct pci_dev *dev)
{
- /*
- * For XLP PCIe, there is an IRQ per Link, find out which
- * link the device is on to assign interrupts
- */
- if (dev->bus->self == NULL)
- return 0;
+ struct pci_bus *bus, *p;
- switch (dev->bus->self->devfn) {
- case 0x8:
- return PIC_PCIE_LINK_0_IRQ;
- case 0x9:
- return PIC_PCIE_LINK_1_IRQ;
- case 0xa:
- return PIC_PCIE_LINK_2_IRQ;
- case 0xb:
- return PIC_PCIE_LINK_3_IRQ;
- }
- WARN(1, "Unexpected devfn %d\n", dev->bus->self->devfn);
- return 0;
+ /* Find the bridge on bus 0 */
+ bus = dev->bus;
+ for (p = bus->parent; p && p->number != 0; p = p->parent)
+ bus = p;
+
+ return p ? bus->self : NULL;
+}
+
+static inline int nlm_pci_link_to_irq(int link)
+{
+ return PIC_PCIE_LINK_0_IRQ + link;
}
int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
- return get_irq_vector(dev);
+ struct pci_dev *lnkdev;
+ int lnkslot, lnkfunc, irq;
+
+ /*
+ * For XLP PCIe, there is an IRQ per Link, find out which
+ * link the device is on to assign interrupts
+ */
+ lnkdev = xlp_get_pcie_link(dev);
+ if (lnkdev == NULL)
+ return 0;
+ lnkfunc = PCI_FUNC(lnkdev->devfn);
+ lnkslot = PCI_SLOT(lnkdev->devfn);
+ return nlm_irq_to_xirq(lnkslot / 8, nlm_pci_link_to_irq(lnkfunc));
}
/* Do platform specific device initialization at pci_enable_device() time */
@@ -196,43 +203,41 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
}
#ifdef __BIG_ENDIAN
-static int xlp_enable_pci_bswap(void)
+static int xlp_enable_pci_bswap(int node, int link)
{
- uint64_t pciebase, sysbase;
- int node, i;
+ uint64_t nbubase, lnkbase;
u32 reg;
- /* Chip-0 so node set to 0 */
- node = 0;
- sysbase = nlm_get_bridge_regbase(node);
+ nbubase = nlm_get_bridge_regbase(node);
+ lnkbase = nlm_get_pcie_base(node, link);
+
/*
* Enable byte swap in hardware. Program each link's PCIe SWAP regions
* from the link's address ranges.
*/
- for (i = 0; i < 4; i++) {
- pciebase = nlm_pcicfg_base(XLP_IO_PCIE_OFFSET(node, i));
- if (nlm_read_pci_reg(pciebase, 0) == 0xffffffff)
- continue;
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEMEM_BASE0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_BASE, reg);
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_BASE0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_BASE, reg);
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEMEM_LIMIT0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_LIM, reg | 0xfff);
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_LIMIT0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_LIM,
- reg | 0xfff);
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_BASE0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_BASE, reg);
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_BASE0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_BASE, reg);
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_LIMIT0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_LIMIT0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
- }
return 0;
}
#endif
static int __init pcibios_init(void)
{
+ struct nlm_soc_info *nodep;
+ uint64_t pciebase;
+ int link, n;
+ u32 reg;
+
/* Firmware assigns PCI resources */
pci_set_flags(PCI_PROBE_ONLY);
pci_config_base = ioremap(XLP_DEFAULT_PCI_ECFG_BASE, 64 << 20);
@@ -241,9 +246,28 @@ static int __init pcibios_init(void)
ioport_resource.start = 0;
ioport_resource.end = ~0;
+ for (n = 0; n < NLM_NR_NODES; n++) {
+ nodep = nlm_get_node(n);
+ if (!nodep->coremask)
+ continue; /* node does not exist */
+
+ for (link = 0; link < 4; link++) {
+ pciebase = nlm_get_pcie_base(n, link);
+ if (nlm_read_pci_reg(pciebase, 0) == 0xffffffff)
+ continue;
#ifdef __BIG_ENDIAN
- xlp_enable_pci_bswap();
+ xlp_enable_pci_bswap(n, link);
#endif
+
+ /* put in intpin and irq - u-boot does not */
+ reg = nlm_read_pci_reg(pciebase, 0xf);
+ reg &= ~0x1fu;
+ reg |= (1 << 8) | nlm_pci_link_to_irq(link);
+ nlm_write_pci_reg(pciebase, 0xf, reg);
+ pr_info("XLP PCIe: Link %d initialized\n", link);
+ }
+ }
+
set_io_port_base(CKSEG1);
nlm_pci_controller.io_map_base = CKSEG1;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 03/10] MIPS: PCI: Byteswap not needed in little-endian mode
2013-01-14 16:11 ` [PATCH 03/10] MIPS: PCI: Byteswap not needed in little-endian mode Jayachandran C
@ 2013-01-14 17:48 ` Sergei Shtylyov
2013-01-15 6:19 ` Jayachandran C
1 sibling, 0 replies; 21+ messages in thread
From: Sergei Shtylyov @ 2013-01-14 17:48 UTC (permalink / raw)
To: Jayachandran C; +Cc: linux-mips, ralf
Hello.
On 01/14/2013 07:11 PM, Jayachandran C wrote:
> Wrap the xlp_enable_pci_bswap() function and its call with
> '#ifdef __BIG_ENDIAN'. On Netlogic XLP, the PCIe initialization code
> to setup to byteswap is needed only in big-endian mode.
> Signed-off-by: Jayachandran C <jchandra@broadcom.com>
> ---
> arch/mips/pci/pci-xlp.c | 4 ++++
> 1 file changed, 4 insertions(+)
> diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c
> index 140557a..fe435fc 100644
> --- a/arch/mips/pci/pci-xlp.c
> +++ b/arch/mips/pci/pci-xlp.c
> @@ -191,6 +191,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
> return 0;
> }
>
> +#ifdef __BIG_ENDIAN
> static int xlp_enable_pci_bswap(void)
> {
> uint64_t pciebase, sysbase;
> @@ -224,6 +225,7 @@ static int xlp_enable_pci_bswap(void)
> }
> return 0;
> }
> +#endif
>
> static int __init pcibios_init(void)
> {
> @@ -235,7 +237,9 @@ static int __init pcibios_init(void)
> ioport_resource.start = 0;
> ioport_resource.end = ~0;
>
> +#ifdef __BIG_ENDIAN
> xlp_enable_pci_bswap();
> +#endif
Define empty inline function for the non-BE case instead. That's what
Documentation/SubmittingPatches tells us to do.
WBR, Sergei
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 03/10] MIPS: PCI: Byteswap not needed in little-endian mode
2013-01-14 16:11 ` [PATCH 03/10] MIPS: PCI: Byteswap not needed in little-endian mode Jayachandran C
2013-01-14 17:48 ` Sergei Shtylyov
@ 2013-01-15 6:19 ` Jayachandran C
2013-01-15 11:58 ` Sergei Shtylyov
1 sibling, 1 reply; 21+ messages in thread
From: Jayachandran C @ 2013-01-15 6:19 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
Wrap the xlp_enable_pci_bswap() function and its call with
'#ifdef __BIG_ENDIAN'. On Netlogic XLP, the PCIe initialization code
to setup to byteswap is needed only in big-endian mode.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/pci/pci-xlp.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c
index 140557a..d201efa 100644
--- a/arch/mips/pci/pci-xlp.c
+++ b/arch/mips/pci/pci-xlp.c
@@ -191,8 +191,14 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
return 0;
}
-static int xlp_enable_pci_bswap(void)
+/*
+ * If big-endian, enable hardware byteswap on the PCIe bridges.
+ * This will make both the SoC and PCIe devices behave consistently with
+ * readl/writel.
+ */
+static void xlp_config_pci_bswap(void)
{
+#ifdef __BIG_ENDIAN
uint64_t pciebase, sysbase;
int node, i;
u32 reg;
@@ -222,7 +228,7 @@ static int xlp_enable_pci_bswap(void)
reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_LIMIT0 + i);
nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
}
- return 0;
+#endif
}
static int __init pcibios_init(void)
@@ -235,7 +241,7 @@ static int __init pcibios_init(void)
ioport_resource.start = 0;
ioport_resource.end = ~0;
- xlp_enable_pci_bswap();
+ xlp_config_pci_bswap();
set_io_port_base(CKSEG1);
nlm_pci_controller.io_map_base = CKSEG1;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 10/10] MIPS: PCI: Multi-node PCI support for Netlogic XLP
2013-01-14 16:12 ` [PATCH 10/10] MIPS: PCI: Multi-node PCI support for Netlogic XLP Jayachandran C
@ 2013-01-15 6:20 ` Jayachandran C
2013-01-15 6:38 ` Jayachandran C
1 sibling, 0 replies; 21+ messages in thread
From: Jayachandran C @ 2013-01-15 6:20 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
On a multi-chip XLP board, each node can have 4 PCIe links. Update
XLP PCI code to initialize PCI on all the nodes.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/pci/pci-xlp.c | 107 ++++++++++++++++++++++++++++-------------------
1 file changed, 65 insertions(+), 42 deletions(-)
diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c
index 5f1a6de..920b715 100644
--- a/arch/mips/pci/pci-xlp.c
+++ b/arch/mips/pci/pci-xlp.c
@@ -46,6 +46,7 @@
#include <asm/netlogic/interrupt.h>
#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/common.h>
#include <asm/netlogic/xlp-hal/iomap.h>
#include <asm/netlogic/xlp-hal/pic.h>
@@ -161,32 +162,38 @@ struct pci_controller nlm_pci_controller = {
.io_offset = 0x00000000UL,
};
-static int get_irq_vector(const struct pci_dev *dev)
+static struct pci_dev *xlp_get_pcie_link(const struct pci_dev *dev)
{
- /*
- * For XLP PCIe, there is an IRQ per Link, find out which
- * link the device is on to assign interrupts
- */
- if (dev->bus->self == NULL)
- return 0;
+ struct pci_bus *bus, *p;
- switch (dev->bus->self->devfn) {
- case 0x8:
- return PIC_PCIE_LINK_0_IRQ;
- case 0x9:
- return PIC_PCIE_LINK_1_IRQ;
- case 0xa:
- return PIC_PCIE_LINK_2_IRQ;
- case 0xb:
- return PIC_PCIE_LINK_3_IRQ;
- }
- WARN(1, "Unexpected devfn %d\n", dev->bus->self->devfn);
- return 0;
+ /* Find the bridge on bus 0 */
+ bus = dev->bus;
+ for (p = bus->parent; p && p->number != 0; p = p->parent)
+ bus = p;
+
+ return p ? bus->self : NULL;
+}
+
+static inline int nlm_pci_link_to_irq(int link)
+{
+ return PIC_PCIE_LINK_0_IRQ + link;
}
int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
- return get_irq_vector(dev);
+ struct pci_dev *lnkdev;
+ int lnkslot, lnkfunc, irq;
+
+ /*
+ * For XLP PCIe, there is an IRQ per Link, find out which
+ * link the device is on to assign interrupts
+ */
+ lnkdev = xlp_get_pcie_link(dev);
+ if (lnkdev == NULL)
+ return 0;
+ lnkfunc = PCI_FUNC(lnkdev->devfn);
+ lnkslot = PCI_SLOT(lnkdev->devfn);
+ return nlm_irq_to_xirq(lnkslot / 8, nlm_pci_link_to_irq(lnkfunc));
}
/* Do platform specific device initialization at pci_enable_device() time */
@@ -200,43 +207,40 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
* This will make both the SoC and PCIe devices behave consistently with
* readl/writel.
*/
-static void xlp_config_pci_bswap(void)
+static int xlp_config_pci_bswap(int node, int link)
{
#ifdef __BIG_ENDIAN
- uint64_t pciebase, sysbase;
- int node, i;
+ uint64_t nbubase, lnkbase;
u32 reg;
- /* Chip-0 so node set to 0 */
- node = 0;
- sysbase = nlm_get_bridge_regbase(node);
+ nbubase = nlm_get_bridge_regbase(node);
+ lnkbase = nlm_get_pcie_base(node, link);
+
/*
* Enable byte swap in hardware. Program each link's PCIe SWAP regions
* from the link's address ranges.
*/
- for (i = 0; i < 4; i++) {
- pciebase = nlm_pcicfg_base(XLP_IO_PCIE_OFFSET(node, i));
- if (nlm_read_pci_reg(pciebase, 0) == 0xffffffff)
- continue;
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEMEM_BASE0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_BASE, reg);
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_BASE0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_BASE, reg);
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEMEM_LIMIT0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_LIM, reg | 0xfff);
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_LIMIT0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_LIM,
- reg | 0xfff);
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_BASE0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_BASE, reg);
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_BASE0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_BASE, reg);
-
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_LIMIT0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
- }
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_LIMIT0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
#endif
}
static int __init pcibios_init(void)
{
+ struct nlm_soc_info *nodep;
+ uint64_t pciebase;
+ int link, n;
+ u32 reg;
+
/* Firmware assigns PCI resources */
pci_set_flags(PCI_PROBE_ONLY);
pci_config_base = ioremap(XLP_DEFAULT_PCI_ECFG_BASE, 64 << 20);
@@ -245,7 +249,26 @@ static int __init pcibios_init(void)
ioport_resource.start = 0;
ioport_resource.end = ~0;
- xlp_config_pci_bswap();
+ for (n = 0; n < NLM_NR_NODES; n++) {
+ nodep = nlm_get_node(n);
+ if (!nodep->coremask)
+ continue; /* node does not exist */
+
+ for (link = 0; link < 4; link++) {
+ pciebase = nlm_get_pcie_base(n, link);
+ if (nlm_read_pci_reg(pciebase, 0) == 0xffffffff)
+ continue;
+ xlp_config_pci_bswap(n, link);
+
+ /* put in intpin and irq - u-boot does not */
+ reg = nlm_read_pci_reg(pciebase, 0xf);
+ reg &= ~0x1fu;
+ reg |= (1 << 8) | nlm_pci_link_to_irq(link);
+ nlm_write_pci_reg(pciebase, 0xf, reg);
+ pr_info("XLP PCIe: Link %d-%d initialized.\n", n, link);
+ }
+ }
+
set_io_port_base(CKSEG1);
nlm_pci_controller.io_map_base = CKSEG1;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 10/10] MIPS: PCI: Multi-node PCI support for Netlogic XLP
2013-01-14 16:12 ` [PATCH 10/10] MIPS: PCI: Multi-node PCI support for Netlogic XLP Jayachandran C
2013-01-15 6:20 ` Jayachandran C
@ 2013-01-15 6:38 ` Jayachandran C
2013-01-15 6:38 ` [PATCH 03/10] MIPS: PCI: Byteswap not needed in little-endian mode Jayachandran C
1 sibling, 1 reply; 21+ messages in thread
From: Jayachandran C @ 2013-01-15 6:38 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
On a multi-chip XLP board, each node can have 4 PCIe links. Update
XLP PCI code to initialize PCI on all the nodes.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/pci/pci-xlp.c | 107 ++++++++++++++++++++++++++++-------------------
1 file changed, 65 insertions(+), 42 deletions(-)
diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c
index 5f1a6de..920b715 100644
--- a/arch/mips/pci/pci-xlp.c
+++ b/arch/mips/pci/pci-xlp.c
@@ -46,6 +46,7 @@
#include <asm/netlogic/interrupt.h>
#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/common.h>
#include <asm/netlogic/xlp-hal/iomap.h>
#include <asm/netlogic/xlp-hal/pic.h>
@@ -161,32 +162,38 @@ struct pci_controller nlm_pci_controller = {
.io_offset = 0x00000000UL,
};
-static int get_irq_vector(const struct pci_dev *dev)
+static struct pci_dev *xlp_get_pcie_link(const struct pci_dev *dev)
{
- /*
- * For XLP PCIe, there is an IRQ per Link, find out which
- * link the device is on to assign interrupts
- */
- if (dev->bus->self == NULL)
- return 0;
+ struct pci_bus *bus, *p;
- switch (dev->bus->self->devfn) {
- case 0x8:
- return PIC_PCIE_LINK_0_IRQ;
- case 0x9:
- return PIC_PCIE_LINK_1_IRQ;
- case 0xa:
- return PIC_PCIE_LINK_2_IRQ;
- case 0xb:
- return PIC_PCIE_LINK_3_IRQ;
- }
- WARN(1, "Unexpected devfn %d\n", dev->bus->self->devfn);
- return 0;
+ /* Find the bridge on bus 0 */
+ bus = dev->bus;
+ for (p = bus->parent; p && p->number != 0; p = p->parent)
+ bus = p;
+
+ return p ? bus->self : NULL;
+}
+
+static inline int nlm_pci_link_to_irq(int link)
+{
+ return PIC_PCIE_LINK_0_IRQ + link;
}
int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
- return get_irq_vector(dev);
+ struct pci_dev *lnkdev;
+ int lnkslot, lnkfunc, irq;
+
+ /*
+ * For XLP PCIe, there is an IRQ per Link, find out which
+ * link the device is on to assign interrupts
+ */
+ lnkdev = xlp_get_pcie_link(dev);
+ if (lnkdev == NULL)
+ return 0;
+ lnkfunc = PCI_FUNC(lnkdev->devfn);
+ lnkslot = PCI_SLOT(lnkdev->devfn);
+ return nlm_irq_to_xirq(lnkslot / 8, nlm_pci_link_to_irq(lnkfunc));
}
/* Do platform specific device initialization at pci_enable_device() time */
@@ -200,43 +207,40 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
* This will make both the SoC and PCIe devices behave consistently with
* readl/writel.
*/
-static void xlp_config_pci_bswap(void)
+static int xlp_config_pci_bswap(int node, int link)
{
#ifdef __BIG_ENDIAN
- uint64_t pciebase, sysbase;
- int node, i;
+ uint64_t nbubase, lnkbase;
u32 reg;
- /* Chip-0 so node set to 0 */
- node = 0;
- sysbase = nlm_get_bridge_regbase(node);
+ nbubase = nlm_get_bridge_regbase(node);
+ lnkbase = nlm_get_pcie_base(node, link);
+
/*
* Enable byte swap in hardware. Program each link's PCIe SWAP regions
* from the link's address ranges.
*/
- for (i = 0; i < 4; i++) {
- pciebase = nlm_pcicfg_base(XLP_IO_PCIE_OFFSET(node, i));
- if (nlm_read_pci_reg(pciebase, 0) == 0xffffffff)
- continue;
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEMEM_BASE0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_BASE, reg);
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_BASE0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_BASE, reg);
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEMEM_LIMIT0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_LIM, reg | 0xfff);
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_LIMIT0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_LIM,
- reg | 0xfff);
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_BASE0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_BASE, reg);
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_BASE0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_BASE, reg);
-
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_LIMIT0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
- }
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_LIMIT0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
#endif
}
static int __init pcibios_init(void)
{
+ struct nlm_soc_info *nodep;
+ uint64_t pciebase;
+ int link, n;
+ u32 reg;
+
/* Firmware assigns PCI resources */
pci_set_flags(PCI_PROBE_ONLY);
pci_config_base = ioremap(XLP_DEFAULT_PCI_ECFG_BASE, 64 << 20);
@@ -245,7 +249,26 @@ static int __init pcibios_init(void)
ioport_resource.start = 0;
ioport_resource.end = ~0;
- xlp_config_pci_bswap();
+ for (n = 0; n < NLM_NR_NODES; n++) {
+ nodep = nlm_get_node(n);
+ if (!nodep->coremask)
+ continue; /* node does not exist */
+
+ for (link = 0; link < 4; link++) {
+ pciebase = nlm_get_pcie_base(n, link);
+ if (nlm_read_pci_reg(pciebase, 0) == 0xffffffff)
+ continue;
+ xlp_config_pci_bswap(n, link);
+
+ /* put in intpin and irq - u-boot does not */
+ reg = nlm_read_pci_reg(pciebase, 0xf);
+ reg &= ~0x1fu;
+ reg |= (1 << 8) | nlm_pci_link_to_irq(link);
+ nlm_write_pci_reg(pciebase, 0xf, reg);
+ pr_info("XLP PCIe: Link %d-%d initialized.\n", n, link);
+ }
+ }
+
set_io_port_base(CKSEG1);
nlm_pci_controller.io_map_base = CKSEG1;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 03/10] MIPS: PCI: Byteswap not needed in little-endian mode
2013-01-15 6:38 ` Jayachandran C
@ 2013-01-15 6:38 ` Jayachandran C
2013-01-16 12:12 ` Jayachandran C
0 siblings, 1 reply; 21+ messages in thread
From: Jayachandran C @ 2013-01-15 6:38 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
Rename xlp_enable_pci_bswap() to xlp_config_pci_bswap(), and add
'#ifdef __BIG_ENDIAN' to its contents so that it is an empty function
when compiled in little-endian mode.
On Netlogic XLP, the PCIe initialization code to enable byteswap is
needed only in big-endian mode.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
[Update comments to reflect changes in updated patch. The changes are
based on a suggestion on #ifdef usage by sshtylyov@mvista.com ]
arch/mips/pci/pci-xlp.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c
index 140557a..d201efa 100644
--- a/arch/mips/pci/pci-xlp.c
+++ b/arch/mips/pci/pci-xlp.c
@@ -191,8 +191,14 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
return 0;
}
-static int xlp_enable_pci_bswap(void)
+/*
+ * If big-endian, enable hardware byteswap on the PCIe bridges.
+ * This will make both the SoC and PCIe devices behave consistently with
+ * readl/writel.
+ */
+static void xlp_config_pci_bswap(void)
{
+#ifdef __BIG_ENDIAN
uint64_t pciebase, sysbase;
int node, i;
u32 reg;
@@ -222,7 +228,7 @@ static int xlp_enable_pci_bswap(void)
reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_LIMIT0 + i);
nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
}
- return 0;
+#endif
}
static int __init pcibios_init(void)
@@ -235,7 +241,7 @@ static int __init pcibios_init(void)
ioport_resource.start = 0;
ioport_resource.end = ~0;
- xlp_enable_pci_bswap();
+ xlp_config_pci_bswap();
set_io_port_base(CKSEG1);
nlm_pci_controller.io_map_base = CKSEG1;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 03/10] MIPS: PCI: Byteswap not needed in little-endian mode
2013-01-15 6:19 ` Jayachandran C
@ 2013-01-15 11:58 ` Sergei Shtylyov
2013-01-15 12:16 ` Florian Fainelli
0 siblings, 1 reply; 21+ messages in thread
From: Sergei Shtylyov @ 2013-01-15 11:58 UTC (permalink / raw)
To: Jayachandran C; +Cc: linux-mips, ralf
Hello.
On 15-01-2013 10:19, Jayachandran C wrote:
> Wrap the xlp_enable_pci_bswap() function and its call with
> '#ifdef __BIG_ENDIAN'. On Netlogic XLP, the PCIe initialization code
> to setup to byteswap is needed only in big-endian mode.
> Signed-off-by: Jayachandran C <jchandra@broadcom.com>
> ---
> arch/mips/pci/pci-xlp.c | 12 +++++++++---
> 1 file changed, 9 insertions(+), 3 deletions(-)
> diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c
> index 140557a..d201efa 100644
> --- a/arch/mips/pci/pci-xlp.c
> +++ b/arch/mips/pci/pci-xlp.c
> @@ -191,8 +191,14 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
> return 0;
> }
>
> -static int xlp_enable_pci_bswap(void)
> +/*
> + * If big-endian, enable hardware byteswap on the PCIe bridges.
> + * This will make both the SoC and PCIe devices behave consistently with
> + * readl/writel.
> + */
> +static void xlp_config_pci_bswap(void)
> {
> +#ifdef __BIG_ENDIAN
> uint64_t pciebase, sysbase;
> int node, i;
> u32 reg;
> @@ -222,7 +228,7 @@ static int xlp_enable_pci_bswap(void)
> reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_LIMIT0 + i);
> nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
> }
> - return 0;
> +#endif
You misunderstood. #ifdef within functions are frowned upon. Thios patch
is hardly better than previous then.
WBR, Sergei
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 03/10] MIPS: PCI: Byteswap not needed in little-endian mode
2013-01-15 11:58 ` Sergei Shtylyov
@ 2013-01-15 12:16 ` Florian Fainelli
0 siblings, 0 replies; 21+ messages in thread
From: Florian Fainelli @ 2013-01-15 12:16 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: Jayachandran C, linux-mips, ralf
On 01/15/2013 12:58 PM, Sergei Shtylyov wrote:
> Hello.
>
> On 15-01-2013 10:19, Jayachandran C wrote:
>
>> Wrap the xlp_enable_pci_bswap() function and its call with
>> '#ifdef __BIG_ENDIAN'. On Netlogic XLP, the PCIe initialization code
>> to setup to byteswap is needed only in big-endian mode.
>
>> Signed-off-by: Jayachandran C <jchandra@broadcom.com>
[snip]
>> +/*
>> + * If big-endian, enable hardware byteswap on the PCIe bridges.
>> + * This will make both the SoC and PCIe devices behave consistently with
>> + * readl/writel.
>> + */
>> +static void xlp_config_pci_bswap(void)
>> {
>> +#ifdef __BIG_ENDIAN
>> uint64_t pciebase, sysbase;
>> int node, i;
>> u32 reg;
>> @@ -222,7 +228,7 @@ static int xlp_enable_pci_bswap(void)
>> reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_LIMIT0 + i);
>> nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_LIM, reg |
>> 0xfff);
>> }
>> - return 0;
>> +#endif
>
> You misunderstood. #ifdef within functions are frowned upon. Thios
> patch is hardly better than previous then.
Jayachandran, you probably need something like this:
#ifdef __BIG_ENDIAN
static void xlp_config_pci_bswap(void)
{
/* perform the actual swapping */
}
#else
static inline void xlp_config_pci_bswap(void) { }
#endif
--
Florian
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 04/10] MIPS: Netlogic: Split XLP L1 i-cache among threads
2013-01-14 16:11 ` [PATCH 04/10] MIPS: Netlogic: Split XLP L1 i-cache among threads Jayachandran C
@ 2013-01-15 18:04 ` Ralf Baechle
0 siblings, 0 replies; 21+ messages in thread
From: Ralf Baechle @ 2013-01-15 18:04 UTC (permalink / raw)
To: Jayachandran C; +Cc: linux-mips
On Mon, Jan 14, 2013 at 09:41:56PM +0530, Jayachandran C wrote:
> Since we now use r4k cache code for Netlogic XLP, it is
> better to split L1 icache among the active threads, so that
> threads won't step on each other while flushing icache.
>
> The L1 dcache is already split among the threads in the core.
It's a bit orthogonal to your patch but you may want to look at adding
support for SYS_SUPPORTS_SCHED_SMT which scheduler support for SMT that
is tries to schedule threads in a shared cache friendly way. See
0ab7aefc4d43a6dee26c891b41ef9c7a67d2379b [[MIPS] MT: Scheduler support for
SMT].
Ralf
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 03/10] MIPS: PCI: Byteswap not needed in little-endian mode
2013-01-15 6:38 ` [PATCH 03/10] MIPS: PCI: Byteswap not needed in little-endian mode Jayachandran C
@ 2013-01-16 12:12 ` Jayachandran C
2013-01-16 12:12 ` [PATCH 10/10] MIPS: PCI: Multi-node PCI support for Netlogic XLP Jayachandran C
0 siblings, 1 reply; 21+ messages in thread
From: Jayachandran C @ 2013-01-16 12:12 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
Rename function xlp_enable_pci_bswap() to xlp_config_pci_bswap(), which
is a better description for its functionality. When compiled in
big-endian mode, xlp_config_pci_bswap() will configure the PCIe links
to byteswap. In little-endian mode, no swap configuration is needed
for the PCIe controller, and the function is empty.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
[ New version with updated #ifdef style ]
arch/mips/pci/pci-xlp.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c
index 140557a..5077148 100644
--- a/arch/mips/pci/pci-xlp.c
+++ b/arch/mips/pci/pci-xlp.c
@@ -191,7 +191,13 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
return 0;
}
-static int xlp_enable_pci_bswap(void)
+/*
+ * If big-endian, enable hardware byteswap on the PCIe bridges.
+ * This will make both the SoC and PCIe devices behave consistently with
+ * readl/writel.
+ */
+#ifdef __BIG_ENDIAN
+static void xlp_config_pci_bswap(void)
{
uint64_t pciebase, sysbase;
int node, i;
@@ -222,8 +228,11 @@ static int xlp_enable_pci_bswap(void)
reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_LIMIT0 + i);
nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
}
- return 0;
}
+#else
+/* Swap configuration not needed in little-endian mode */
+static inline void xlp_config_pci_bswap(void) {}
+#endif /* __BIG_ENDIAN */
static int __init pcibios_init(void)
{
@@ -235,7 +244,7 @@ static int __init pcibios_init(void)
ioport_resource.start = 0;
ioport_resource.end = ~0;
- xlp_enable_pci_bswap();
+ xlp_config_pci_bswap();
set_io_port_base(CKSEG1);
nlm_pci_controller.io_map_base = CKSEG1;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 10/10] MIPS: PCI: Multi-node PCI support for Netlogic XLP
2013-01-16 12:12 ` Jayachandran C
@ 2013-01-16 12:12 ` Jayachandran C
0 siblings, 0 replies; 21+ messages in thread
From: Jayachandran C @ 2013-01-16 12:12 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
On a multi-chip XLP board, each node can have 4 PCIe links. Update
XLP PCI code to initialize PCIe on all the nodes.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
[ Updated for the new PATCH 3/10]
arch/mips/pci/pci-xlp.c | 109 ++++++++++++++++++++++++++++-------------------
1 file changed, 66 insertions(+), 43 deletions(-)
diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c
index fbf001a..dd2d3eb 100644
--- a/arch/mips/pci/pci-xlp.c
+++ b/arch/mips/pci/pci-xlp.c
@@ -46,6 +46,7 @@
#include <asm/netlogic/interrupt.h>
#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/common.h>
#include <asm/netlogic/xlp-hal/iomap.h>
#include <asm/netlogic/xlp-hal/pic.h>
@@ -161,32 +162,38 @@ struct pci_controller nlm_pci_controller = {
.io_offset = 0x00000000UL,
};
-static int get_irq_vector(const struct pci_dev *dev)
+static struct pci_dev *xlp_get_pcie_link(const struct pci_dev *dev)
{
- /*
- * For XLP PCIe, there is an IRQ per Link, find out which
- * link the device is on to assign interrupts
- */
- if (dev->bus->self == NULL)
- return 0;
+ struct pci_bus *bus, *p;
- switch (dev->bus->self->devfn) {
- case 0x8:
- return PIC_PCIE_LINK_0_IRQ;
- case 0x9:
- return PIC_PCIE_LINK_1_IRQ;
- case 0xa:
- return PIC_PCIE_LINK_2_IRQ;
- case 0xb:
- return PIC_PCIE_LINK_3_IRQ;
- }
- WARN(1, "Unexpected devfn %d\n", dev->bus->self->devfn);
- return 0;
+ /* Find the bridge on bus 0 */
+ bus = dev->bus;
+ for (p = bus->parent; p && p->number != 0; p = p->parent)
+ bus = p;
+
+ return p ? bus->self : NULL;
+}
+
+static inline int nlm_pci_link_to_irq(int link)
+{
+ return PIC_PCIE_LINK_0_IRQ + link;
}
int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
- return get_irq_vector(dev);
+ struct pci_dev *lnkdev;
+ int lnkslot, lnkfunc;
+
+ /*
+ * For XLP PCIe, there is an IRQ per Link, find out which
+ * link the device is on to assign interrupts
+ */
+ lnkdev = xlp_get_pcie_link(dev);
+ if (lnkdev == NULL)
+ return 0;
+ lnkfunc = PCI_FUNC(lnkdev->devfn);
+ lnkslot = PCI_SLOT(lnkdev->devfn);
+ return nlm_irq_to_xirq(lnkslot / 8, nlm_pci_link_to_irq(lnkfunc));
}
/* Do platform specific device initialization at pci_enable_device() time */
@@ -201,45 +208,42 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
* readl/writel.
*/
#ifdef __BIG_ENDIAN
-static void xlp_config_pci_bswap(void)
+static void xlp_config_pci_bswap(int node, int link)
{
- uint64_t pciebase, sysbase;
- int node, i;
+ uint64_t nbubase, lnkbase;
u32 reg;
- /* Chip-0 so node set to 0 */
- node = 0;
- sysbase = nlm_get_bridge_regbase(node);
+ nbubase = nlm_get_bridge_regbase(node);
+ lnkbase = nlm_get_pcie_base(node, link);
+
/*
* Enable byte swap in hardware. Program each link's PCIe SWAP regions
* from the link's address ranges.
*/
- for (i = 0; i < 4; i++) {
- pciebase = nlm_pcicfg_base(XLP_IO_PCIE_OFFSET(node, i));
- if (nlm_read_pci_reg(pciebase, 0) == 0xffffffff)
- continue;
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEMEM_BASE0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_BASE, reg);
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_BASE0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_BASE, reg);
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEMEM_LIMIT0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_LIM, reg | 0xfff);
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_LIMIT0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_LIM,
- reg | 0xfff);
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_BASE0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_BASE, reg);
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_BASE0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_BASE, reg);
-
- reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_LIMIT0 + i);
- nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
- }
+ reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_LIMIT0 + link);
+ nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
}
#else
/* Swap configuration not needed in little-endian mode */
-static inline void xlp_config_pci_bswap(void) {}
+static inline void xlp_config_pci_bswap(int node, int link) {}
#endif /* __BIG_ENDIAN */
static int __init pcibios_init(void)
{
+ struct nlm_soc_info *nodep;
+ uint64_t pciebase;
+ int link, n;
+ u32 reg;
+
/* Firmware assigns PCI resources */
pci_set_flags(PCI_PROBE_ONLY);
pci_config_base = ioremap(XLP_DEFAULT_PCI_ECFG_BASE, 64 << 20);
@@ -248,7 +252,26 @@ static int __init pcibios_init(void)
ioport_resource.start = 0;
ioport_resource.end = ~0;
- xlp_config_pci_bswap();
+ for (n = 0; n < NLM_NR_NODES; n++) {
+ nodep = nlm_get_node(n);
+ if (!nodep->coremask)
+ continue; /* node does not exist */
+
+ for (link = 0; link < 4; link++) {
+ pciebase = nlm_get_pcie_base(n, link);
+ if (nlm_read_pci_reg(pciebase, 0) == 0xffffffff)
+ continue;
+ xlp_config_pci_bswap(n, link);
+
+ /* put in intpin and irq - u-boot does not */
+ reg = nlm_read_pci_reg(pciebase, 0xf);
+ reg &= ~0x1fu;
+ reg |= (1 << 8) | nlm_pci_link_to_irq(link);
+ nlm_write_pci_reg(pciebase, 0xf, reg);
+ pr_info("XLP PCIe: Link %d-%d initialized.\n", n, link);
+ }
+ }
+
set_io_port_base(CKSEG1);
nlm_pci_controller.io_map_base = CKSEG1;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
end of thread, other threads:[~2013-01-16 12:10 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-14 16:11 [PATCH 00/10] Netlogic: Fixes and updates for 3.9 Jayachandran C
2013-01-14 16:11 ` [PATCH 01/10] MIPS: Netlogic: add XLS6xx to FMN config Jayachandran C
2013-01-14 16:11 ` [PATCH 02/10] MIPS: Netlogic: Optimize EIMR/EIRR accesses in 32-bit Jayachandran C
2013-01-14 16:11 ` [PATCH 03/10] MIPS: PCI: Byteswap not needed in little-endian mode Jayachandran C
2013-01-14 17:48 ` Sergei Shtylyov
2013-01-15 6:19 ` Jayachandran C
2013-01-15 11:58 ` Sergei Shtylyov
2013-01-15 12:16 ` Florian Fainelli
2013-01-14 16:11 ` [PATCH 04/10] MIPS: Netlogic: Split XLP L1 i-cache among threads Jayachandran C
2013-01-15 18:04 ` Ralf Baechle
2013-01-14 16:11 ` [PATCH 05/10] MIPS: Netlogic: Use PIC timer as a clocksource Jayachandran C
2013-01-14 16:11 ` [PATCH 06/10] MIPS: PCI: Prevent hang on XLP reg read Jayachandran C
2013-01-14 16:11 ` [PATCH 07/10] MIPS: Netlogic: No hazards needed for XLR/XLS Jayachandran C
2013-01-14 16:12 ` [PATCH 08/10] MIPS: Netlogic: use preset loops per jiffy Jayachandran C
2013-01-14 16:12 ` [PATCH 09/10] MIPS: Netlogic: Fix for quad-XLP boot Jayachandran C
2013-01-14 16:12 ` [PATCH 10/10] MIPS: PCI: Multi-node PCI support for Netlogic XLP Jayachandran C
2013-01-15 6:20 ` Jayachandran C
2013-01-15 6:38 ` Jayachandran C
2013-01-15 6:38 ` [PATCH 03/10] MIPS: PCI: Byteswap not needed in little-endian mode Jayachandran C
2013-01-16 12:12 ` Jayachandran C
2013-01-16 12:12 ` [PATCH 10/10] MIPS: PCI: Multi-node PCI support for Netlogic XLP Jayachandran C
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox