diff options
Diffstat (limited to 'arch/arc/plat-arcfpga')
-rw-r--r-- | arch/arc/plat-arcfpga/Kconfig | 84 | ||||
-rw-r--r-- | arch/arc/plat-arcfpga/Makefile | 12 | ||||
-rw-r--r-- | arch/arc/plat-arcfpga/include/plat/irq.h | 31 | ||||
-rw-r--r-- | arch/arc/plat-arcfpga/include/plat/memmap.h | 31 | ||||
-rw-r--r-- | arch/arc/plat-arcfpga/include/plat/smp.h | 118 | ||||
-rw-r--r-- | arch/arc/plat-arcfpga/irq.c | 25 | ||||
-rw-r--r-- | arch/arc/plat-arcfpga/platform.c | 226 | ||||
-rw-r--r-- | arch/arc/plat-arcfpga/smp.c | 171 |
8 files changed, 698 insertions, 0 deletions
diff --git a/arch/arc/plat-arcfpga/Kconfig b/arch/arc/plat-arcfpga/Kconfig new file mode 100644 index 00000000000..b41e786cdbc --- /dev/null +++ b/arch/arc/plat-arcfpga/Kconfig @@ -0,0 +1,84 @@ +# +# Copyright (C) 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# + +menuconfig ARC_PLAT_FPGA_LEGACY + bool "\"Legacy\" ARC FPGA dev Boards" + select ISS_SMP_EXTN if SMP + help + Support for ARC development boards, provided by Synopsys. + These are based on FPGA or ISS. e.g. + - ARCAngel4 + - ML509 + - MetaWare ISS + +if ARC_PLAT_FPGA_LEGACY + +config ARC_BOARD_ANGEL4 + bool "ARC Angel4" + default y + help + ARC Angel4 FPGA Ref Platform (Xilinx Virtex Based) + +config ARC_BOARD_ML509 + bool "ML509" + help + ARC ML509 FPGA Ref Platform (Xilinx Virtex-5 Based) + +config ISS_SMP_EXTN + bool "ARC SMP Extensions (ISS Models only)" + default n + depends on SMP + select ARC_HAS_COH_RTSC + help + SMP Extensions to ARC700, in a "simulation only" Model, supported in + ARC ISS (Instruction Set Simulator). + The SMP extensions include: + -IDU (Interrupt Distribution Unit) + -XTL (To enable CPU start/stop/set-PC for another CPU) + It doesn't provide coherent Caches and/or Atomic Ops (LLOCK/SCOND) + +config ARC_SERIAL_BAUD + int "UART Baud rate" + default "115200" + depends on SERIAL_ARC || SERIAL_ARC_CONSOLE + help + Baud rate for the ARC UART + +menuconfig ARC_HAS_BVCI_LAT_UNIT + bool "BVCI Bus Latency Unit" + depends on ARC_BOARD_ML509 || ARC_BOARD_ANGEL4 + help + IP to add artifical latency to BVCI Bus Based FPGA builds. + The default latency (even worst case) for FPGA is non-realistic + (~10 SDRAM, ~5 SSRAM). + +config BVCI_LAT_UNITS + hex "Latency Unit(s) Bitmap" + default "0x0" + depends on ARC_HAS_BVCI_LAT_UNIT + help + There are multiple Latency Units corresponding to the many + interfaces of the system bus arbiter (both CPU side as well as + the peripheral side). + To add latency to ALL memory transaction, choose Unit 0, otherwise + for finer grainer - interface wise latency, specify a bitmap (1 bit + per unit) of all units. e.g. 1,2,12 will be 0x1003 + + Unit 0 - System Arb and Mem Controller + Unit 1 - I$ and System Bus + Unit 2 - D$ and System Bus + .. + Unit 12 - IDE Disk controller and System Bus + +config BVCI_LAT_CYCLES + int "Latency Value in cycles" + range 0 63 + default "30" + depends on ARC_HAS_BVCI_LAT_UNIT + +endif diff --git a/arch/arc/plat-arcfpga/Makefile b/arch/arc/plat-arcfpga/Makefile new file mode 100644 index 00000000000..a44e22ebc1b --- /dev/null +++ b/arch/arc/plat-arcfpga/Makefile @@ -0,0 +1,12 @@ +# +# Copyright (C) 2011-2012 Synopsys, Inc. (www.synopsys.com) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# + +KBUILD_CFLAGS += -Iarch/arc/plat-arcfpga/include + +obj-y := platform.o irq.o +obj-$(CONFIG_SMP) += smp.o diff --git a/arch/arc/plat-arcfpga/include/plat/irq.h b/arch/arc/plat-arcfpga/include/plat/irq.h new file mode 100644 index 00000000000..41e335670f6 --- /dev/null +++ b/arch/arc/plat-arcfpga/include/plat/irq.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * vineetg: Feb 2009 + * -For AA4 board, IRQ assignments to peripherals + */ + +#ifndef __PLAT_IRQ_H +#define __PLAT_IRQ_H + +#define UART0_IRQ 5 +#define UART1_IRQ 10 +#define UART2_IRQ 11 + +#define VMAC_IRQ 6 + +#define IDE_IRQ 13 +#define PCI_IRQ 14 +#define PS2_IRQ 15 + +#ifdef CONFIG_SMP +#define IDU_INTERRUPT_0 16 +#endif + +extern void __init plat_fpga_init_IRQ(void); + +#endif diff --git a/arch/arc/plat-arcfpga/include/plat/memmap.h b/arch/arc/plat-arcfpga/include/plat/memmap.h new file mode 100644 index 00000000000..1663f338808 --- /dev/null +++ b/arch/arc/plat-arcfpga/include/plat/memmap.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * vineetg: Feb 2009 + * -For AA4 board, System Memory Map for Peripherals etc + */ + +#ifndef __PLAT_MEMMAP_H +#define __PLAT_MEMMAP_H + +#define UART0_BASE 0xC0FC1000 +#define UART1_BASE 0xC0FC1100 + +#define VMAC_REG_BASEADDR 0xC0FC2000 + +#define IDE_CONTROLLER_BASE 0xC0FC9000 + +#define AHB_PCI_HOST_BRG_BASE 0xC0FD0000 + +#define PGU_BASEADDR 0xC0FC8000 +#define VLCK_ADDR 0xC0FCF028 + +#define BVCI_LAT_UNIT_BASE 0xC0FED000 + +#define PS2_BASE_ADDR 0xC0FCC000 + +#endif diff --git a/arch/arc/plat-arcfpga/include/plat/smp.h b/arch/arc/plat-arcfpga/include/plat/smp.h new file mode 100644 index 00000000000..c09eb4cfc77 --- /dev/null +++ b/arch/arc/plat-arcfpga/include/plat/smp.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Rajeshwar Ranga: Interrupt Distribution Unit API's + */ + +#ifndef __PLAT_ARCFPGA_SMP_H +#define __PLAT_ARCFPGA_SMP_H + +#ifdef CONFIG_SMP + +#include <linux/types.h> +#include <asm/arcregs.h> + +#define ARC_AUX_IDU_REG_CMD 0x2000 +#define ARC_AUX_IDU_REG_PARAM 0x2001 + +#define ARC_AUX_XTL_REG_CMD 0x2002 +#define ARC_AUX_XTL_REG_PARAM 0x2003 + +#define ARC_REG_MP_BCR 0x2021 + +#define ARC_XTL_CMD_WRITE_PC 0x04 +#define ARC_XTL_CMD_CLEAR_HALT 0x02 + +/* + * Build Configuration Register which identifies the sub-components + */ +struct bcr_mp { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned int mp_arch:16, pad:5, sdu:1, idu:1, scu:1, ver:8; +#else + unsigned int ver:8, scu:1, idu:1, sdu:1, pad:5, mp_arch:16; +#endif +}; + +/* IDU supports 256 common interrupts */ +#define NR_IDU_IRQS 256 + +/* + * The Aux Regs layout is same bit-by-bit in both BE/LE modes. + * However when casted as a bitfield encoded "C" struct, gcc treats it as + * memory, generating different code for BE/LE, requiring strcture adj (see + * include/asm/arcregs.h) + * + * However when manually "carving" the value for a Aux, no special handling + * of BE is needed because of the property discribed above + */ +#define IDU_SET_COMMAND(irq, cmd) \ +do { \ + uint32_t __val; \ + __val = (((irq & 0xFF) << 8) | (cmd & 0xFF)); \ + write_aux_reg(ARC_AUX_IDU_REG_CMD, __val); \ +} while (0) + +#define IDU_SET_PARAM(par) write_aux_reg(ARC_AUX_IDU_REG_PARAM, par) +#define IDU_GET_PARAM() read_aux_reg(ARC_AUX_IDU_REG_PARAM) + +/* IDU Commands */ +#define IDU_DISABLE 0x00 +#define IDU_ENABLE 0x01 +#define IDU_IRQ_CLEAR 0x02 +#define IDU_IRQ_ASSERT 0x03 +#define IDU_IRQ_WMODE 0x04 +#define IDU_IRQ_STATUS 0x05 +#define IDU_IRQ_ACK 0x06 +#define IDU_IRQ_PEND 0x07 +#define IDU_IRQ_RMODE 0x08 +#define IDU_IRQ_WBITMASK 0x09 +#define IDU_IRQ_RBITMASK 0x0A + +#define idu_enable() IDU_SET_COMMAND(0, IDU_ENABLE) +#define idu_disable() IDU_SET_COMMAND(0, IDU_DISABLE) + +#define idu_irq_assert(irq) IDU_SET_COMMAND((irq), IDU_IRQ_ASSERT) +#define idu_irq_clear(irq) IDU_SET_COMMAND((irq), IDU_IRQ_CLEAR) + +/* IDU Interrupt Mode - Destination Encoding */ +#define IDU_IRQ_MOD_DISABLE 0x00 +#define IDU_IRQ_MOD_ROUND_RECP 0x01 +#define IDU_IRQ_MOD_TCPU_FIRSTRECP 0x02 +#define IDU_IRQ_MOD_TCPU_ALLRECP 0x03 + +/* IDU Interrupt Mode - Triggering Mode */ +#define IDU_IRQ_MODE_LEVEL_TRIG 0x00 +#define IDU_IRQ_MODE_PULSE_TRIG 0x01 + +#define IDU_IRQ_MODE_PARAM(dest_mode, trig_mode) \ + (((trig_mode & 0x01) << 15) | (dest_mode & 0xFF)) + +struct idu_irq_config { + uint8_t irq; + uint8_t dest_mode; + uint8_t trig_mode; +}; + +struct idu_irq_status { + uint8_t irq; + bool enabled; + bool status; + bool ack; + bool pend; + uint8_t next_rr; +}; + +extern void idu_irq_set_tgtcpu(uint8_t irq, uint32_t mask); +extern void idu_irq_set_mode(uint8_t irq, uint8_t dest_mode, uint8_t trig_mode); + +extern void iss_model_init_smp(unsigned int cpu); +extern void iss_model_init_early_smp(void); + +#endif /* CONFIG_SMP */ + +#endif diff --git a/arch/arc/plat-arcfpga/irq.c b/arch/arc/plat-arcfpga/irq.c new file mode 100644 index 00000000000..d2215fd889c --- /dev/null +++ b/arch/arc/plat-arcfpga/irq.c @@ -0,0 +1,25 @@ +/* + * ARC FPGA Platform IRQ hookups + * + * Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/interrupt.h> +#include <plat/irq.h> + +void __init plat_fpga_init_IRQ(void) +{ + /* + * SMP Hack because UART IRQ hardwired to cpu0 (boot-cpu) but if the + * request_irq() comes from any other CPU, the low level IRQ unamsking + * essential for getting Interrupts won't be enabled on cpu0, locking + * up the UART state machine. + */ +#ifdef CONFIG_SMP + arch_unmask_irq(UART0_IRQ); +#endif +} diff --git a/arch/arc/plat-arcfpga/platform.c b/arch/arc/plat-arcfpga/platform.c new file mode 100644 index 00000000000..4e20a1a5104 --- /dev/null +++ b/arch/arc/plat-arcfpga/platform.c @@ -0,0 +1,226 @@ +/* + * ARC FPGA Platform support code + * + * Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/console.h> +#include <linux/of_platform.h> +#include <asm/setup.h> +#include <asm/clk.h> +#include <asm/mach_desc.h> +#include <plat/memmap.h> +#include <plat/smp.h> +#include <plat/irq.h> + +/*-----------------------BVCI Latency Unit -----------------------------*/ + +#ifdef CONFIG_ARC_HAS_BVCI_LAT_UNIT + +int lat_cycles = CONFIG_BVCI_LAT_CYCLES; + +/* BVCI Bus Profiler: Latency Unit */ +static void __init setup_bvci_lat_unit(void) +{ +#define MAX_BVCI_UNITS 12 + + unsigned int i; + unsigned int *base = (unsigned int *)BVCI_LAT_UNIT_BASE; + const unsigned long units_req = CONFIG_BVCI_LAT_UNITS; + const unsigned int REG_UNIT = 21; + const unsigned int REG_VAL = 22; + + /* + * There are multiple Latency Units corresponding to the many + * interfaces of the system bus arbiter (both CPU side as well as + * the peripheral side). + * + * Unit 0 - System Arb and Mem Controller - adds latency to all + * memory trasactions + * Unit 1 - I$ and System Bus + * Unit 2 - D$ and System Bus + * .. + * Unit 12 - IDE Disk controller and System Bus + * + * The programmers model requires writing to lat_unit reg first + * and then the latency value (cycles) to lat_value reg + */ + + if (CONFIG_BVCI_LAT_UNITS == 0) { + writel(0, base + REG_UNIT); + writel(lat_cycles, base + REG_VAL); + pr_info("BVCI Latency for all Memory Transactions %d cycles\n", + lat_cycles); + } else { + for_each_set_bit(i, &units_req, MAX_BVCI_UNITS) { + writel(i + 1, base + REG_UNIT); /* loop is 0 based */ + writel(lat_cycles, base + REG_VAL); + pr_info("BVCI Latency for Unit[%d] = %d cycles\n", + (i + 1), lat_cycles); + } + } +} +#else +static void __init setup_bvci_lat_unit(void) +{ +} +#endif + +/*----------------------- Platform Devices -----------------------------*/ + +static unsigned long arc_uart_info[] = { + 0, /* uart->is_emulated (runtime @running_on_hw) */ + 0, /* uart->port.uartclk */ + 0, /* uart->baud */ + 0 +}; + +#if defined(CONFIG_SERIAL_ARC_CONSOLE) +/* + * static platform data - but only for early serial + * TBD: derive this from a special DT node + */ +static struct resource arc_uart0_res[] = { + { + .start = UART0_BASE, + .end = UART0_BASE + 0xFF, + .flags = IORESOURCE_MEM, + }, + { + .start = UART0_IRQ, + .end = UART0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device arc_uart0_dev = { + .name = "arc-uart", + .id = 0, + .num_resources = ARRAY_SIZE(arc_uart0_res), + .resource = arc_uart0_res, + .dev = { + .platform_data = &arc_uart_info, + }, +}; + +static struct platform_device *fpga_early_devs[] __initdata = { + &arc_uart0_dev, +}; +#endif + +static void arc_fpga_serial_init(void) +{ + /* To let driver workaround ISS bug: baudh Reg can't be set to 0 */ + arc_uart_info[0] = !running_on_hw; + + arc_uart_info[1] = arc_get_core_freq(); + + arc_uart_info[2] = CONFIG_ARC_SERIAL_BAUD; + +#if defined(CONFIG_SERIAL_ARC_CONSOLE) + early_platform_add_devices(fpga_early_devs, + ARRAY_SIZE(fpga_early_devs)); + + /* + * ARC console driver registers itself as an early platform driver + * of class "earlyprintk". + * Install it here, followed by probe of devices. + * The installation here doesn't require earlyprintk in command line + * To do so however, replace the lines below with + * parse_early_param(); + * early_platform_driver_probe("earlyprintk", 1, 1); + * ^^ + */ + early_platform_driver_register_all("earlyprintk"); + early_platform_driver_probe("earlyprintk", 1, 0); + + /* + * This is to make sure that arc uart would be preferred console + * despite one/more of following: + * -command line lacked "console=ttyARC0" or + * -CONFIG_VT_CONSOLE was enabled (for no reason whatsoever) + * Note that this needs to be done after above early console is reg, + * otherwise the early console never gets a chance to run. + */ + add_preferred_console("ttyARC", 0, "115200"); +#endif +} + +static void __init plat_fpga_early_init(void) +{ + pr_info("[plat-arcfpga]: registering early dev resources\n"); + + setup_bvci_lat_unit(); + + arc_fpga_serial_init(); + +#ifdef CONFIG_SMP + iss_model_init_early_smp(); +#endif +} + +static struct of_dev_auxdata plat_auxdata_lookup[] __initdata = { +#if defined(CONFIG_SERIAL_ARC) || defined(CONFIG_SERIAL_ARC_MODULE) + OF_DEV_AUXDATA("snps,arc-uart", UART0_BASE, "arc-uart", arc_uart_info), +#endif + {} +}; + +static void __init plat_fpga_populate_dev(void) +{ + pr_info("[plat-arcfpga]: registering device resources\n"); + + /* + * Traverses flattened DeviceTree - registering platform devices + * complete with their resources + */ + of_platform_populate(NULL, of_default_bus_match_table, + plat_auxdata_lookup, NULL); +} + +/*----------------------- Machine Descriptions ------------------------------ + * + * Machine description is simply a set of platform/board specific callbacks + * This is not directly related to DeviceTree based dynamic device creation, + * however as part of early device tree scan, we also select the right + * callback set, by matching the DT compatible name. + */ + +static const char *aa4_compat[] __initdata = { + "snps,arc-angel4", + NULL, +}; + +MACHINE_START(ANGEL4, "angel4") + .dt_compat = aa4_compat, + .init_early = plat_fpga_early_init, + .init_machine = plat_fpga_populate_dev, + .init_irq = plat_fpga_init_IRQ, +#ifdef CONFIG_SMP + .init_smp = iss_model_init_smp, +#endif +MACHINE_END + +static const char *ml509_compat[] __initdata = { + "snps,arc-ml509", + NULL, +}; + +MACHINE_START(ML509, "ml509") + .dt_compat = ml509_compat, + .init_early = plat_fpga_early_init, + .init_machine = plat_fpga_populate_dev, + .init_irq = plat_fpga_init_IRQ, +#ifdef CONFIG_SMP + .init_smp = iss_model_init_smp, +#endif +MACHINE_END diff --git a/arch/arc/plat-arcfpga/smp.c b/arch/arc/plat-arcfpga/smp.c new file mode 100644 index 00000000000..91b55349a5f --- /dev/null +++ b/arch/arc/plat-arcfpga/smp.c @@ -0,0 +1,171 @@ +/* + * ARC700 Simulation-only Extensions for SMP + * + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Vineet Gupta - 2012 : split off arch common and plat specific SMP + * Rajeshwar Ranga - 2007 : Interrupt Distribution Unit API's + */ + +#include <linux/smp.h> +#include <linux/irq.h> +#include <plat/irq.h> +#include <plat/smp.h> + +static char smp_cpuinfo_buf[128]; + +/* + *------------------------------------------------------------------- + * Platform specific callbacks expected by arch SMP code + *------------------------------------------------------------------- + */ + +/* + * Master kick starting another CPU + */ +static void iss_model_smp_wakeup_cpu(int cpu, unsigned long pc) +{ + /* setup the start PC */ + write_aux_reg(ARC_AUX_XTL_REG_PARAM, pc); + + /* Trigger WRITE_PC cmd for this cpu */ + write_aux_reg(ARC_AUX_XTL_REG_CMD, + (ARC_XTL_CMD_WRITE_PC | (cpu << 8))); + + /* Take the cpu out of Halt */ + write_aux_reg(ARC_AUX_XTL_REG_CMD, + (ARC_XTL_CMD_CLEAR_HALT | (cpu << 8))); + +} + +/* + * Any SMP specific init any CPU does when it comes up. + * Here we setup the CPU to enable Inter-Processor-Interrupts + * Called for each CPU + * -Master : init_IRQ() + * -Other(s) : start_kernel_secondary() + */ +void iss_model_init_smp(unsigned int cpu) +{ + /* Check if CPU is configured for more than 16 interrupts */ + if (NR_IRQS <= 16 || get_hw_config_num_irq() <= 16) + panic("[arcfpga] IRQ system can't support IDU IPI\n"); + + idu_disable(); + + /**************************************************************** + * IDU provides a set of Common IRQs, each of which can be dynamically + * attached to (1|many|all) CPUs. + * The Common IRQs [0-15] are mapped as CPU pvt [16-31] + * + * Here we use a simple 1:1 mapping: + * A CPU 'x' is wired to Common IRQ 'x'. + * So an IDU ASSERT on IRQ 'x' will trigger Interupt on CPU 'x', which + * makes up for our simple IPI plumbing. + * + * TBD: Have a dedicated multicast IRQ for sending IPIs to all CPUs + * w/o having to do one-at-a-time + ******************************************************************/ + + /* + * Claim an IRQ which would trigger IPI on this CPU. + * In IDU parlance it involves setting up a cpu bitmask for the IRQ + * The bitmap here contains only 1 CPU (self). + */ + idu_irq_set_tgtcpu(cpu, 0x1 << cpu); + + /* Set the IRQ destination to use the bitmask above */ + idu_irq_set_mode(cpu, 7, /* XXX: IDU_IRQ_MOD_TCPU_ALLRECP: ISS bug */ + IDU_IRQ_MODE_PULSE_TRIG); + + idu_enable(); + + /* Attach the arch-common IPI ISR to our IDU IRQ */ + smp_ipi_irq_setup(cpu, IDU_INTERRUPT_0 + cpu); +} + +static void iss_model_ipi_send(void *arg) +{ + struct cpumask *callmap = arg; + unsigned int cpu; + + for_each_cpu(cpu, callmap) + idu_irq_assert(cpu); +} + +static void iss_model_ipi_clear(int cpu, int irq) +{ + idu_irq_clear(IDU_INTERRUPT_0 + cpu); +} + +void iss_model_init_early_smp(void) +{ +#define IS_AVAIL1(var, str) ((var) ? str : "") + + struct bcr_mp mp; + + READ_BCR(ARC_REG_MP_BCR, mp); + + sprintf(smp_cpuinfo_buf, "Extn [ISS-SMP]: v%d, arch(%d) %s %s %s\n", + mp.ver, mp.mp_arch, IS_AVAIL1(mp.scu, "SCU"), + IS_AVAIL1(mp.idu, "IDU"), IS_AVAIL1(mp.sdu, "SDU")); + + plat_smp_ops.info = smp_cpuinfo_buf; + + plat_smp_ops.cpu_kick = iss_model_smp_wakeup_cpu; + plat_smp_ops.ipi_send = iss_model_ipi_send; + plat_smp_ops.ipi_clear = iss_model_ipi_clear; +} + +/* + *------------------------------------------------------------------- + * Low level Platform IPI Providers + *------------------------------------------------------------------- + */ + +/* Set the Mode for the Common IRQ */ +void idu_irq_set_mode(uint8_t irq, uint8_t dest_mode, uint8_t trig_mode) +{ + uint32_t par = IDU_IRQ_MODE_PARAM(dest_mode, trig_mode); + + IDU_SET_PARAM(par); + IDU_SET_COMMAND(irq, IDU_IRQ_WMODE); +} + +/* Set the target cpu Bitmask for Common IRQ */ +void idu_irq_set_tgtcpu(uint8_t irq, uint32_t mask) +{ + IDU_SET_PARAM(mask); + IDU_SET_COMMAND(irq, IDU_IRQ_WBITMASK); +} + +/* Get the Interrupt Acknowledged status for IRQ (as CPU Bitmask) */ +bool idu_irq_get_ack(uint8_t irq) +{ + uint32_t val; + + IDU_SET_COMMAND(irq, IDU_IRQ_ACK); + val = IDU_GET_PARAM(); + + return val & (1 << irq); +} + +/* + * Get the Interrupt Pending status for IRQ (as CPU Bitmask) + * -Pending means CPU has not yet noticed the IRQ (e.g. disabled) + * -After Interrupt has been taken, the IPI expcitily needs to be + * cleared, to be acknowledged. + */ +bool idu_irq_get_pend(uint8_t irq) +{ + uint32_t val; + + IDU_SET_COMMAND(irq, IDU_IRQ_PEND); + val = IDU_GET_PARAM(); + + return val & (1 << irq); +} |