Merge branch 'mips-next-3.9' of git://git.linux-mips.org/pub/scm/john/linux-john into mips-for-linux-next
This commit is contained in:
@@ -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)
|
||||
@@ -230,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;
|
||||
@@ -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)
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -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 */
|
||||
|
@@ -35,17 +35,73 @@
|
||||
#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();
|
||||
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);
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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, \
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user