ARC updates for 4.10-rc1 (part 1)
- Moving ARC timer driver into drivers/clocksource - EZChip timer driver updates [Noam] - ARC AXS103 and HAPS platform updates [Alexey] -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJYUtJVAAoJEGnX8d3iisJeA3cP/0jAuNqNfjQKkWgMkN0BAoy4 K+P+Ky1KwWS4eSdTI0DUVg4rkH4K5KPWpE/khXAkc71x1AjTJymyMVxE3w5teiyj YjK92B1PajjZtRm33+kjphe4g2a+FlSbvFtDW0irkYD3MLwtOheeZVpxFWTu2cGh IyQSj/u7s+qKlWgZhxskvtH3MX/d2K3CXI5qOwdrrUjLuN/4I7mpwPh/lfH09/Uu FE/+OVuoYzsbdI1LLMvkzf/h4WnxaDclUGzKt93U7YAGRAObw6Yng26nCeA50EQd ugyqVsJP2b4RyZuMqcb2bllO4z9QPpqexP2xxYDC2VYfZaFFrsy+ofzF3I6yfHyq qaoeFWlBU+P4GnanqVdJjJylDzpET+TtaadIAotY7Z/+ZKHHz6a06MLAibzHzpR6 idmBE9QCOXgo8eb4Rkp4ZsP7C1oaMcPRdD2DJsMU2+faVDanCfahe1ZgqDebEPoi g4KW8iMHrhmc3aL/depxImGl321NhE5UI05SmJX7wNs2TTEdFestC762tSbc4kTu OgE5UEC0b+u0Hp0ED86AbYDqsqQmVC/2aI07tlXd2M0OojGs9gZoMkLH/5ImzsZr N9sIjzZnRD2lLu8RiS9+niLXbSZ8sQ2gSlzXh9tVK5bd1hHx22OwTJftX9jy3lcb RnsnGZdzOeLgbd2lWjms =1Hlx -----END PGP SIGNATURE----- Merge tag 'arc-4.10-rc1-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc Pull ARC updates from Vineet Gupta: "These are mostly timer/clocksource driver updates which were Reviewed/Acked by Daniel but had to be merged via ARC tree due to dependencies. I will follow up with another pull request with actual ARC changes early next week ! Summary: - Moving ARC timer driver into drivers/clocksource - EZChip timer driver updates [Noam] - ARC AXS103 and HAPS platform updates [Alexey]" * tag 'arc-4.10-rc1-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: ARC: axs10x: really enable ARC PGU ARC: rename Zebu platform support to HAPS clocksource: nps: avoid maybe-uninitialized warning clocksource: Add clockevent support to NPS400 driver clocksource: update "fn" at CLOCKSOURCE_OF_DECLARE() of nps400 timer soc: Support for NPS HW scheduling clocksource: import ARC timer driver ARC: breakout timer include code into separate header ... ARC: move mcip.h into include/soc and adjust the includes ARC: breakout aux handling into a separate header ARC: time: move time_init() out of the driver ARC: timer: gfrc, rtc: build under same option (64-bit timers) ARC: timer: gfrc, rtc: Read BCR to detect whether hardware exists ... ARC: timer: gfrc, rtc: deuglify big endian code
This commit is contained in:
commit
d25b6af91e
|
@ -0,0 +1,17 @@
|
|||
NPS Network Processor
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be "ezchip,nps400-timer0"
|
||||
|
||||
Clocks required for compatible = "ezchip,nps400-timer0":
|
||||
- interrupts : The interrupt of the first timer
|
||||
- clocks : Must contain a single entry describing the clock input
|
||||
|
||||
Example:
|
||||
|
||||
timer {
|
||||
compatible = "ezchip,nps400-timer0";
|
||||
interrupts = <3>;
|
||||
clocks = <&sysclk>;
|
||||
};
|
|
@ -2,14 +2,14 @@ NPS Network Processor
|
|||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be "ezchip,nps400-timer"
|
||||
- compatible : should be "ezchip,nps400-timer1"
|
||||
|
||||
Clocks required for compatible = "ezchip,nps400-timer":
|
||||
Clocks required for compatible = "ezchip,nps400-timer1":
|
||||
- clocks : Must contain a single entry describing the clock input
|
||||
|
||||
Example:
|
||||
|
||||
timer {
|
||||
compatible = "ezchip,nps400-timer";
|
||||
compatible = "ezchip,nps400-timer1";
|
||||
clocks = <&sysclk>;
|
||||
};
|
|
@ -11827,6 +11827,7 @@ S: Supported
|
|||
F: arch/arc/
|
||||
F: Documentation/devicetree/bindings/arc/*
|
||||
F: Documentation/devicetree/bindings/interrupt-controller/snps,arc*
|
||||
F: drivers/clocksource/arc_timer.c
|
||||
F: drivers/tty/serial/arc_uart.c
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
config ARC
|
||||
def_bool y
|
||||
select ARC_TIMERS
|
||||
select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC
|
||||
select BUILDTIME_EXTABLE_SORT
|
||||
select CLKSRC_OF
|
||||
select CLONE_BACKWARDS
|
||||
select COMMON_CLK
|
||||
select GENERIC_ATOMIC64 if !ISA_ARCV2 || !(ARC_HAS_LL64 && ARC_HAS_LLSC)
|
||||
|
@ -115,6 +115,7 @@ config ISA_ARCOMPACT
|
|||
|
||||
config ISA_ARCV2
|
||||
bool "ARC ISA v2"
|
||||
select ARC_TIMERS_64BIT
|
||||
help
|
||||
ISA for the Next Generation ARC-HS cores
|
||||
|
||||
|
@ -410,16 +411,6 @@ config ARC_HAS_DIV_REM
|
|||
bool "Insn: div, divu, rem, remu"
|
||||
default y
|
||||
|
||||
config ARC_HAS_RTC
|
||||
bool "Local 64-bit r/o cycle counter"
|
||||
default n
|
||||
depends on !SMP
|
||||
|
||||
config ARC_HAS_GFRC
|
||||
bool "SMP synchronized 64-bit cycle counter"
|
||||
default y
|
||||
depends on SMP
|
||||
|
||||
config ARC_NUMBER_OF_INTERRUPTS
|
||||
int "Number of interrupts"
|
||||
range 8 240
|
||||
|
|
|
@ -17,6 +17,6 @@
|
|||
compatible = "snps,axs101", "snps,arc-sdp";
|
||||
|
||||
chosen {
|
||||
bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 consoleblank=0";
|
||||
bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 consoleblank=0 video=1280x720@60";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -20,6 +20,6 @@
|
|||
compatible = "snps,axs103", "snps,arc-sdp";
|
||||
|
||||
chosen {
|
||||
bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=ttyS3,115200n8 debug print-fatal-signals=1";
|
||||
bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 print-fatal-signals=1 consoleblank=0 video=1280x720@60";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -75,9 +75,11 @@ CONFIG_I2C=y
|
|||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_DESIGNWARE_PLATFORM=y
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_DRM=m
|
||||
CONFIG_DRM_I2C_ADV7511=m
|
||||
CONFIG_DRM_ARCPGU=m
|
||||
CONFIG_FB=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
||||
CONFIG_LOGO=y
|
||||
# CONFIG_LOGO_LINUX_MONO is not set
|
||||
# CONFIG_LOGO_LINUX_VGA16 is not set
|
||||
|
|
|
@ -77,9 +77,11 @@ CONFIG_I2C=y
|
|||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_DESIGNWARE_PLATFORM=y
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_DRM=m
|
||||
CONFIG_DRM_I2C_ADV7511=m
|
||||
CONFIG_DRM_ARCPGU=m
|
||||
CONFIG_FB=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
||||
CONFIG_LOGO=y
|
||||
# CONFIG_LOGO_LINUX_MONO is not set
|
||||
# CONFIG_LOGO_LINUX_VGA16 is not set
|
||||
|
|
|
@ -23,7 +23,7 @@ CONFIG_MODULES=y
|
|||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_ARC_PLAT_SIM=y
|
||||
CONFIG_ISA_ARCV2=y
|
||||
CONFIG_ARC_BUILTIN_DTB_NAME="zebu_hs"
|
||||
CONFIG_ARC_BUILTIN_DTB_NAME="haps_hs"
|
||||
CONFIG_PREEMPT=y
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_NET=y
|
|
@ -26,7 +26,7 @@ CONFIG_MODULES=y
|
|||
CONFIG_ARC_PLAT_SIM=y
|
||||
CONFIG_ISA_ARCV2=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_ARC_BUILTIN_DTB_NAME="zebu_hs_idu"
|
||||
CONFIG_ARC_BUILTIN_DTB_NAME="haps_hs_idu"
|
||||
CONFIG_PREEMPT=y
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_NET=y
|
|
@ -21,7 +21,7 @@ CONFIG_MODULES=y
|
|||
CONFIG_ARC_PLAT_SIM=y
|
||||
CONFIG_ISA_ARCV2=y
|
||||
CONFIG_SMP=y
|
||||
# CONFIG_ARC_HAS_GFRC is not set
|
||||
# CONFIG_ARC_TIMERS_64BIT is not set
|
||||
CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci_hs_idu"
|
||||
CONFIG_PREEMPT=y
|
||||
# CONFIG_COMPACTION is not set
|
||||
|
|
|
@ -15,7 +15,7 @@ CONFIG_ARC_PLAT_AXS10X=y
|
|||
CONFIG_AXS103=y
|
||||
CONFIG_ISA_ARCV2=y
|
||||
CONFIG_SMP=y
|
||||
# CONFIG_ARC_HAS_GFRC is not set
|
||||
# CONFIG_ARC_TIMERS_64BIT is not set
|
||||
CONFIG_ARC_UBOOT_SUPPORT=y
|
||||
CONFIG_ARC_BUILTIN_DTB_NAME="vdk_hs38_smp"
|
||||
CONFIG_PREEMPT=y
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#define ARC_REG_FP_V2_BCR 0xc8 /* ARCv2 FPU */
|
||||
#define ARC_REG_SLC_BCR 0xce
|
||||
#define ARC_REG_DCCM_BUILD 0x74 /* DCCM size (common) */
|
||||
#define ARC_REG_TIMERS_BCR 0x75
|
||||
#define ARC_REG_AP_BCR 0x76
|
||||
#define ARC_REG_ICCM_BUILD 0x78 /* ICCM size (common) */
|
||||
#define ARC_REG_XY_MEM_BCR 0x79
|
||||
|
@ -112,90 +111,7 @@
|
|||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
******************************************************************
|
||||
* Inline ASM macros to read/write AUX Regs
|
||||
* Essentially invocation of lr/sr insns from "C"
|
||||
*/
|
||||
|
||||
#if 1
|
||||
|
||||
#define read_aux_reg(reg) __builtin_arc_lr(reg)
|
||||
|
||||
/* gcc builtin sr needs reg param to be long immediate */
|
||||
#define write_aux_reg(reg_immed, val) \
|
||||
__builtin_arc_sr((unsigned int)(val), reg_immed)
|
||||
|
||||
#else
|
||||
|
||||
#define read_aux_reg(reg) \
|
||||
({ \
|
||||
unsigned int __ret; \
|
||||
__asm__ __volatile__( \
|
||||
" lr %0, [%1]" \
|
||||
: "=r"(__ret) \
|
||||
: "i"(reg)); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Aux Reg address is specified as long immediate by caller
|
||||
* e.g.
|
||||
* write_aux_reg(0x69, some_val);
|
||||
* This generates tightest code.
|
||||
*/
|
||||
#define write_aux_reg(reg_imm, val) \
|
||||
({ \
|
||||
__asm__ __volatile__( \
|
||||
" sr %0, [%1] \n" \
|
||||
: \
|
||||
: "ir"(val), "i"(reg_imm)); \
|
||||
})
|
||||
|
||||
/*
|
||||
* Aux Reg address is specified in a variable
|
||||
* * e.g.
|
||||
* reg_num = 0x69
|
||||
* write_aux_reg2(reg_num, some_val);
|
||||
* This has to generate glue code to load the reg num from
|
||||
* memory to a reg hence not recommended.
|
||||
*/
|
||||
#define write_aux_reg2(reg_in_var, val) \
|
||||
({ \
|
||||
unsigned int tmp; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" ld %0, [%2] \n\t" \
|
||||
" sr %1, [%0] \n\t" \
|
||||
: "=&r"(tmp) \
|
||||
: "r"(val), "memory"(®_in_var)); \
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
#define READ_BCR(reg, into) \
|
||||
{ \
|
||||
unsigned int tmp; \
|
||||
tmp = read_aux_reg(reg); \
|
||||
if (sizeof(tmp) == sizeof(into)) { \
|
||||
into = *((typeof(into) *)&tmp); \
|
||||
} else { \
|
||||
extern void bogus_undefined(void); \
|
||||
bogus_undefined(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define WRITE_AUX(reg, into) \
|
||||
{ \
|
||||
unsigned int tmp; \
|
||||
if (sizeof(tmp) == sizeof(into)) { \
|
||||
tmp = (*(unsigned int *)&(into)); \
|
||||
write_aux_reg(reg, tmp); \
|
||||
} else { \
|
||||
extern void bogus_undefined(void); \
|
||||
bogus_undefined(); \
|
||||
} \
|
||||
}
|
||||
#include <soc/arc/aux.h>
|
||||
|
||||
/* Helpers */
|
||||
#define TO_KB(bytes) ((bytes) >> 10)
|
||||
|
@ -291,13 +207,7 @@ struct bcr_fp_arcv2 {
|
|||
#endif
|
||||
};
|
||||
|
||||
struct bcr_timer {
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8;
|
||||
#else
|
||||
unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15;
|
||||
#endif
|
||||
};
|
||||
#include <soc/arc/timers.h>
|
||||
|
||||
struct bcr_bpu_arcompact {
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# Pass UTS_MACHINE for user_regset definition
|
||||
CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
|
||||
|
||||
obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o
|
||||
obj-y := arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o
|
||||
obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o
|
||||
obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o
|
||||
obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
#include <linux/smp.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <soc/arc/mcip.h>
|
||||
#include <asm/irqflags-arcv2.h>
|
||||
#include <asm/mcip.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
static DEFINE_RAW_SPINLOCK(mcip_lock);
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include <linux/fs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/root_dev.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/cpu.h>
|
||||
|
@ -234,11 +236,11 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
|
|||
is_isa_arcompact() ? "ARCompact" : "ARCv2",
|
||||
IS_AVAIL1(cpu->isa.be, "[Big-Endian]"));
|
||||
|
||||
n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ",
|
||||
n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ",
|
||||
IS_AVAIL1(cpu->extn.timer0, "Timer0 "),
|
||||
IS_AVAIL1(cpu->extn.timer1, "Timer1 "),
|
||||
IS_AVAIL2(cpu->extn.rtc, "Local-64-bit-Ctr ",
|
||||
CONFIG_ARC_HAS_RTC));
|
||||
IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_TIMERS_64BIT),
|
||||
IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_TIMERS_64BIT));
|
||||
|
||||
n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s",
|
||||
IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC),
|
||||
|
@ -449,6 +451,15 @@ void __init setup_arch(char **cmdline_p)
|
|||
arc_unwind_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from start_kernel() - boot CPU only
|
||||
*/
|
||||
void __init time_init(void)
|
||||
{
|
||||
of_clk_init(NULL);
|
||||
clocksource_probe();
|
||||
}
|
||||
|
||||
static int __init customize_machine(void)
|
||||
{
|
||||
if (machine_desc->init_machine)
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include <asm/asm-offsets.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mach_desc.h>
|
||||
#include <asm/mcip.h>
|
||||
#include <soc/arc/mcip.h>
|
||||
|
||||
#define AXS_MB_CGU 0xE0010000
|
||||
#define AXS_MB_CREG 0xE0011000
|
||||
|
|
|
@ -46,9 +46,7 @@
|
|||
#define CTOP_AUX_UDMC (CTOP_AUX_BASE + 0x300)
|
||||
|
||||
/* EZchip core instructions */
|
||||
#define CTOP_INST_HWSCHD_OFF_R3 0x3B6F00BF
|
||||
#define CTOP_INST_HWSCHD_OFF_R4 0x3C6F00BF
|
||||
#define CTOP_INST_HWSCHD_RESTORE_R3 0x3E6F70C3
|
||||
#define CTOP_INST_HWSCHD_RESTORE_R4 0x3E6F7103
|
||||
#define CTOP_INST_SCHD_RW 0x3E6F7004
|
||||
#define CTOP_INST_SCHD_RD 0x3E6F7084
|
||||
|
|
|
@ -282,6 +282,26 @@ config CLKSRC_MPS2
|
|||
select CLKSRC_MMIO
|
||||
select CLKSRC_OF
|
||||
|
||||
config ARC_TIMERS
|
||||
bool "Support for 32-bit TIMERn counters in ARC Cores" if COMPILE_TEST
|
||||
depends on GENERIC_CLOCKEVENTS
|
||||
select CLKSRC_OF
|
||||
help
|
||||
These are legacy 32-bit TIMER0 and TIMER1 counters found on all ARC cores
|
||||
(ARC700 as well as ARC HS38).
|
||||
TIMER0 serves as clockevent while TIMER1 provides clocksource
|
||||
|
||||
config ARC_TIMERS_64BIT
|
||||
bool "Support for 64-bit counters in ARC HS38 cores" if COMPILE_TEST
|
||||
depends on GENERIC_CLOCKEVENTS
|
||||
depends on ARC_TIMERS
|
||||
select CLKSRC_OF
|
||||
help
|
||||
This enables 2 different 64-bit timers: RTC (for UP) and GFRC (for SMP)
|
||||
RTC is implemented inside the core, while GFRC sits outside the core in
|
||||
ARConnect IP block. Driver automatically picks one of them for clocksource
|
||||
as appropriate.
|
||||
|
||||
config ARM_ARCH_TIMER
|
||||
bool
|
||||
select CLKSRC_OF if OF
|
||||
|
|
|
@ -51,6 +51,7 @@ obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o
|
|||
obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o
|
||||
obj-$(CONFIG_OXNAS_RPS_TIMER) += timer-oxnas-rps.o
|
||||
|
||||
obj-$(CONFIG_ARC_TIMERS) += arc_timer.o
|
||||
obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
|
||||
obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
|
||||
obj-$(CONFIG_ARMV7M_SYSTICK) += armv7m_systick.o
|
||||
|
|
|
@ -1,32 +1,18 @@
|
|||
/*
|
||||
* Copyright (C) 2016-17 Synopsys, Inc. (www.synopsys.com)
|
||||
* 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: Jan 1011
|
||||
* -sched_clock( ) no longer jiffies based. Uses the same clocksource
|
||||
* as gtod
|
||||
*
|
||||
* Rajeshwarr/Vineetg: Mar 2008
|
||||
* -Implemented CONFIG_GENERIC_TIME (rather deleted arch specific code)
|
||||
* for arch independent gettimeofday()
|
||||
* -Implemented CONFIG_GENERIC_CLOCKEVENTS as base for hrtimers
|
||||
*
|
||||
* Vineetg: Mar 2008: Forked off from time.c which now is time-jiff.c
|
||||
*/
|
||||
|
||||
/* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1
|
||||
* Each can programmed to go from @count to @limit and optionally
|
||||
* interrupt when that happens.
|
||||
* A write to Control Register clears the Interrupt
|
||||
/* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1, Each can be
|
||||
* programmed to go from @count to @limit and optionally interrupt.
|
||||
* We've designated TIMER0 for clockevents and TIMER1 for clocksource
|
||||
*
|
||||
* We've designated TIMER0 for events (clockevents)
|
||||
* while TIMER1 for free running (clocksource)
|
||||
*
|
||||
* Newer ARC700 cores have 64bit clk fetching RTSC insn, preferred over TIMER1
|
||||
* which however is currently broken
|
||||
* ARCv2 based HS38 cores have RTC (in-core) and GFRC (inside ARConnect/MCIP)
|
||||
* which are suitable for UP and SMP based clocksources respectively
|
||||
*/
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
@ -37,23 +23,10 @@
|
|||
#include <linux/cpu.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/arcregs.h>
|
||||
|
||||
#include <asm/mcip.h>
|
||||
#include <soc/arc/timers.h>
|
||||
#include <soc/arc/mcip.h>
|
||||
|
||||
/* Timer related Aux registers */
|
||||
#define ARC_REG_TIMER0_LIMIT 0x23 /* timer 0 limit */
|
||||
#define ARC_REG_TIMER0_CTRL 0x22 /* timer 0 control */
|
||||
#define ARC_REG_TIMER0_CNT 0x21 /* timer 0 count */
|
||||
#define ARC_REG_TIMER1_LIMIT 0x102 /* timer 1 limit */
|
||||
#define ARC_REG_TIMER1_CTRL 0x101 /* timer 1 control */
|
||||
#define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */
|
||||
|
||||
#define TIMER_CTRL_IE (1 << 0) /* Interrupt when Count reaches limit */
|
||||
#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */
|
||||
|
||||
#define ARC_TIMER_MAX 0xFFFFFFFF
|
||||
|
||||
static unsigned long arc_timer_freq;
|
||||
|
||||
|
@ -81,31 +54,24 @@ static int noinline arc_get_timer_clk(struct device_node *node)
|
|||
|
||||
/********** Clock Source Device *********/
|
||||
|
||||
#ifdef CONFIG_ARC_HAS_GFRC
|
||||
#ifdef CONFIG_ARC_TIMERS_64BIT
|
||||
|
||||
static cycle_t arc_read_gfrc(struct clocksource *cs)
|
||||
{
|
||||
unsigned long flags;
|
||||
union {
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
struct { u32 h, l; };
|
||||
#else
|
||||
struct { u32 l, h; };
|
||||
#endif
|
||||
cycle_t full;
|
||||
} stamp;
|
||||
u32 l, h;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
__mcip_cmd(CMD_GFRC_READ_LO, 0);
|
||||
stamp.l = read_aux_reg(ARC_REG_MCIP_READBACK);
|
||||
l = read_aux_reg(ARC_REG_MCIP_READBACK);
|
||||
|
||||
__mcip_cmd(CMD_GFRC_READ_HI, 0);
|
||||
stamp.h = read_aux_reg(ARC_REG_MCIP_READBACK);
|
||||
h = read_aux_reg(ARC_REG_MCIP_READBACK);
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
return stamp.full;
|
||||
return (((cycle_t)h) << 32) | l;
|
||||
}
|
||||
|
||||
static struct clocksource arc_counter_gfrc = {
|
||||
|
@ -118,11 +84,14 @@ static struct clocksource arc_counter_gfrc = {
|
|||
|
||||
static int __init arc_cs_setup_gfrc(struct device_node *node)
|
||||
{
|
||||
int exists = cpuinfo_arc700[0].extn.gfrc;
|
||||
struct mcip_bcr mp;
|
||||
int ret;
|
||||
|
||||
if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected"))
|
||||
READ_BCR(ARC_REG_MCIP_BCR, mp);
|
||||
if (!mp.gfrc) {
|
||||
pr_warn("Global-64-bit-Ctr clocksource not detected");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
ret = arc_get_timer_clk(node);
|
||||
if (ret)
|
||||
|
@ -132,10 +101,6 @@ static int __init arc_cs_setup_gfrc(struct device_node *node)
|
|||
}
|
||||
CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARC_HAS_RTC
|
||||
|
||||
#define AUX_RTC_CTRL 0x103
|
||||
#define AUX_RTC_LOW 0x104
|
||||
#define AUX_RTC_HIGH 0x105
|
||||
|
@ -143,14 +108,7 @@ CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc);
|
|||
static cycle_t arc_read_rtc(struct clocksource *cs)
|
||||
{
|
||||
unsigned long status;
|
||||
union {
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
struct { u32 high, low; };
|
||||
#else
|
||||
struct { u32 low, high; };
|
||||
#endif
|
||||
cycle_t full;
|
||||
} stamp;
|
||||
u32 l, h;
|
||||
|
||||
/*
|
||||
* hardware has an internal state machine which tracks readout of
|
||||
|
@ -159,12 +117,12 @@ static cycle_t arc_read_rtc(struct clocksource *cs)
|
|||
* - high increments after low has been read
|
||||
*/
|
||||
do {
|
||||
stamp.low = read_aux_reg(AUX_RTC_LOW);
|
||||
stamp.high = read_aux_reg(AUX_RTC_HIGH);
|
||||
l = read_aux_reg(AUX_RTC_LOW);
|
||||
h = read_aux_reg(AUX_RTC_HIGH);
|
||||
status = read_aux_reg(AUX_RTC_CTRL);
|
||||
} while (!(status & _BITUL(31)));
|
||||
|
||||
return stamp.full;
|
||||
return (((cycle_t)h) << 32) | l;
|
||||
}
|
||||
|
||||
static struct clocksource arc_counter_rtc = {
|
||||
|
@ -177,15 +135,20 @@ static struct clocksource arc_counter_rtc = {
|
|||
|
||||
static int __init arc_cs_setup_rtc(struct device_node *node)
|
||||
{
|
||||
int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc;
|
||||
struct bcr_timer timer;
|
||||
int ret;
|
||||
|
||||
if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected"))
|
||||
READ_BCR(ARC_REG_TIMERS_BCR, timer);
|
||||
if (!timer.rtc) {
|
||||
pr_warn("Local-64-bit-Ctr clocksource not detected");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/* Local to CPU hence not usable in SMP */
|
||||
if (WARN(IS_ENABLED(CONFIG_SMP), "Local-64-bit-Ctr not usable in SMP"))
|
||||
if (IS_ENABLED(CONFIG_SMP)) {
|
||||
pr_warn("Local-64-bit-Ctr not usable in SMP");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = arc_get_timer_clk(node);
|
||||
if (ret)
|
||||
|
@ -228,7 +191,7 @@ static int __init arc_cs_setup_timer1(struct device_node *node)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX);
|
||||
write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMERN_MAX);
|
||||
write_aux_reg(ARC_REG_TIMER1_CNT, 0);
|
||||
write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH);
|
||||
|
||||
|
@ -306,7 +269,7 @@ static int arc_timer_starting_cpu(unsigned int cpu)
|
|||
|
||||
evt->cpumask = cpumask_of(smp_processor_id());
|
||||
|
||||
clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMER_MAX);
|
||||
clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMERN_MAX);
|
||||
enable_percpu_irq(arc_timer_irq, 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -371,12 +334,3 @@ static int __init arc_of_timer_init(struct device_node *np)
|
|||
return ret;
|
||||
}
|
||||
CLOCKSOURCE_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_of_timer_init);
|
||||
|
||||
/*
|
||||
* Called from start_kernel() - boot CPU only
|
||||
*/
|
||||
void __init time_init(void)
|
||||
{
|
||||
of_clk_init(NULL);
|
||||
clocksource_probe();
|
||||
}
|
|
@ -46,7 +46,36 @@
|
|||
/* This array is per cluster of CPUs (Each NPS400 cluster got 256 CPUs) */
|
||||
static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
|
||||
|
||||
static unsigned long nps_timer_rate;
|
||||
static int __init nps_get_timer_clk(struct device_node *node,
|
||||
unsigned long *timer_freq,
|
||||
struct clk **clk)
|
||||
{
|
||||
int ret;
|
||||
|
||||
*clk = of_clk_get(node, 0);
|
||||
ret = PTR_ERR_OR_ZERO(*clk);
|
||||
if (ret) {
|
||||
pr_err("timer missing clk");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(*clk);
|
||||
if (ret) {
|
||||
pr_err("Couldn't enable parent clk\n");
|
||||
clk_put(*clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*timer_freq = clk_get_rate(*clk);
|
||||
if (!(*timer_freq)) {
|
||||
pr_err("Couldn't get clk rate\n");
|
||||
clk_disable_unprepare(*clk);
|
||||
clk_put(*clk);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cycle_t nps_clksrc_read(struct clocksource *clksrc)
|
||||
{
|
||||
|
@ -55,26 +84,24 @@ static cycle_t nps_clksrc_read(struct clocksource *clksrc)
|
|||
return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]);
|
||||
}
|
||||
|
||||
static int __init nps_setup_clocksource(struct device_node *node,
|
||||
struct clk *clk)
|
||||
static int __init nps_setup_clocksource(struct device_node *node)
|
||||
{
|
||||
int ret, cluster;
|
||||
struct clk *clk;
|
||||
unsigned long nps_timer1_freq;
|
||||
|
||||
|
||||
for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++)
|
||||
nps_msu_reg_low_addr[cluster] =
|
||||
nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
|
||||
NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
|
||||
NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
|
||||
|
||||
ret = clk_prepare_enable(clk);
|
||||
if (ret) {
|
||||
pr_err("Couldn't enable parent clock\n");
|
||||
ret = nps_get_timer_clk(node, &nps_timer1_freq, &clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
nps_timer_rate = clk_get_rate(clk);
|
||||
|
||||
ret = clocksource_mmio_init(nps_msu_reg_low_addr, "EZnps-tick",
|
||||
nps_timer_rate, 301, 32, nps_clksrc_read);
|
||||
ret = clocksource_mmio_init(nps_msu_reg_low_addr, "nps-tick",
|
||||
nps_timer1_freq, 300, 32, nps_clksrc_read);
|
||||
if (ret) {
|
||||
pr_err("Couldn't register clock source.\n");
|
||||
clk_disable_unprepare(clk);
|
||||
|
@ -83,18 +110,175 @@ static int __init nps_setup_clocksource(struct device_node *node,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int __init nps_timer_init(struct device_node *node)
|
||||
CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
|
||||
nps_setup_clocksource);
|
||||
CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clk_src, "ezchip,nps400-timer1",
|
||||
nps_setup_clocksource);
|
||||
|
||||
#ifdef CONFIG_EZNPS_MTM_EXT
|
||||
#include <soc/nps/mtm.h>
|
||||
|
||||
/* Timer related Aux registers */
|
||||
#define NPS_REG_TIMER0_TSI 0xFFFFF850
|
||||
#define NPS_REG_TIMER0_LIMIT 0x23
|
||||
#define NPS_REG_TIMER0_CTRL 0x22
|
||||
#define NPS_REG_TIMER0_CNT 0x21
|
||||
|
||||
/*
|
||||
* Interrupt Enabled (IE) - re-arm the timer
|
||||
* Not Halted (NH) - is cleared when working with JTAG (for debug)
|
||||
*/
|
||||
#define TIMER0_CTRL_IE BIT(0)
|
||||
#define TIMER0_CTRL_NH BIT(1)
|
||||
|
||||
static unsigned long nps_timer0_freq;
|
||||
static unsigned long nps_timer0_irq;
|
||||
|
||||
static void nps_clkevent_rm_thread(void)
|
||||
{
|
||||
struct clk *clk;
|
||||
int thread;
|
||||
unsigned int cflags, enabled_threads;
|
||||
|
||||
clk = of_clk_get(node, 0);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("Can't get timer clock.\n");
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
hw_schd_save(&cflags);
|
||||
|
||||
return nps_setup_clocksource(node, clk);
|
||||
enabled_threads = read_aux_reg(NPS_REG_TIMER0_TSI);
|
||||
|
||||
/* remove thread from TSI1 */
|
||||
thread = read_aux_reg(CTOP_AUX_THREAD_ID);
|
||||
enabled_threads &= ~(1 << thread);
|
||||
write_aux_reg(NPS_REG_TIMER0_TSI, enabled_threads);
|
||||
|
||||
/* Acknowledge and if needed re-arm the timer */
|
||||
if (!enabled_threads)
|
||||
write_aux_reg(NPS_REG_TIMER0_CTRL, TIMER0_CTRL_NH);
|
||||
else
|
||||
write_aux_reg(NPS_REG_TIMER0_CTRL,
|
||||
TIMER0_CTRL_IE | TIMER0_CTRL_NH);
|
||||
|
||||
hw_schd_restore(cflags);
|
||||
}
|
||||
|
||||
CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
|
||||
nps_timer_init);
|
||||
static void nps_clkevent_add_thread(unsigned long delta)
|
||||
{
|
||||
int thread;
|
||||
unsigned int cflags, enabled_threads;
|
||||
|
||||
hw_schd_save(&cflags);
|
||||
|
||||
/* add thread to TSI1 */
|
||||
thread = read_aux_reg(CTOP_AUX_THREAD_ID);
|
||||
enabled_threads = read_aux_reg(NPS_REG_TIMER0_TSI);
|
||||
enabled_threads |= (1 << thread);
|
||||
write_aux_reg(NPS_REG_TIMER0_TSI, enabled_threads);
|
||||
|
||||
/* set next timer event */
|
||||
write_aux_reg(NPS_REG_TIMER0_LIMIT, delta);
|
||||
write_aux_reg(NPS_REG_TIMER0_CNT, 0);
|
||||
write_aux_reg(NPS_REG_TIMER0_CTRL,
|
||||
TIMER0_CTRL_IE | TIMER0_CTRL_NH);
|
||||
|
||||
hw_schd_restore(cflags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Whenever anyone tries to change modes, we just mask interrupts
|
||||
* and wait for the next event to get set.
|
||||
*/
|
||||
static int nps_clkevent_set_state(struct clock_event_device *dev)
|
||||
{
|
||||
nps_clkevent_rm_thread();
|
||||
disable_percpu_irq(nps_timer0_irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nps_clkevent_set_next_event(unsigned long delta,
|
||||
struct clock_event_device *dev)
|
||||
{
|
||||
nps_clkevent_add_thread(delta);
|
||||
enable_percpu_irq(nps_timer0_irq, IRQ_TYPE_NONE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEFINE_PER_CPU(struct clock_event_device, nps_clockevent_device) = {
|
||||
.name = "NPS Timer0",
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.rating = 300,
|
||||
.set_next_event = nps_clkevent_set_next_event,
|
||||
.set_state_oneshot = nps_clkevent_set_state,
|
||||
.set_state_oneshot_stopped = nps_clkevent_set_state,
|
||||
.set_state_shutdown = nps_clkevent_set_state,
|
||||
.tick_resume = nps_clkevent_set_state,
|
||||
};
|
||||
|
||||
static irqreturn_t timer_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct clock_event_device *evt = dev_id;
|
||||
|
||||
nps_clkevent_rm_thread();
|
||||
evt->event_handler(evt);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int nps_timer_starting_cpu(unsigned int cpu)
|
||||
{
|
||||
struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
|
||||
|
||||
evt->cpumask = cpumask_of(smp_processor_id());
|
||||
|
||||
clockevents_config_and_register(evt, nps_timer0_freq, 0, ULONG_MAX);
|
||||
enable_percpu_irq(nps_timer0_irq, IRQ_TYPE_NONE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nps_timer_dying_cpu(unsigned int cpu)
|
||||
{
|
||||
disable_percpu_irq(nps_timer0_irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init nps_setup_clockevent(struct device_node *node)
|
||||
{
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
nps_timer0_irq = irq_of_parse_and_map(node, 0);
|
||||
if (nps_timer0_irq <= 0) {
|
||||
pr_err("clockevent: missing irq");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = nps_get_timer_clk(node, &nps_timer0_freq, &clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Needs apriori irq_set_percpu_devid() done in intc map function */
|
||||
ret = request_percpu_irq(nps_timer0_irq, timer_irq_handler,
|
||||
"Timer0 (per-cpu-tick)",
|
||||
&nps_clockevent_device);
|
||||
if (ret) {
|
||||
pr_err("Couldn't request irq\n");
|
||||
clk_disable_unprepare(clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = cpuhp_setup_state(CPUHP_AP_ARC_TIMER_STARTING,
|
||||
"clockevents/nps:starting",
|
||||
nps_timer_starting_cpu,
|
||||
nps_timer_dying_cpu);
|
||||
if (ret) {
|
||||
pr_err("Failed to setup hotplug state");
|
||||
clk_disable_unprepare(clk);
|
||||
free_percpu_irq(nps_timer0_irq, &nps_clockevent_device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clk_evt, "ezchip,nps400-timer0",
|
||||
nps_setup_clockevent);
|
||||
#endif /* CONFIG_EZNPS_MTM_EXT */
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (C) 2016-2017 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SOC_ARC_AUX_H__
|
||||
#define __SOC_ARC_AUX_H__
|
||||
|
||||
#ifdef CONFIG_ARC
|
||||
|
||||
#define read_aux_reg(r) __builtin_arc_lr(r)
|
||||
|
||||
/* gcc builtin sr needs reg param to be long immediate */
|
||||
#define write_aux_reg(r, v) __builtin_arc_sr((unsigned int)(v), r)
|
||||
|
||||
#else /* !CONFIG_ARC */
|
||||
|
||||
static inline int read_aux_reg(u32 r)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* function helps elide unused variable warning
|
||||
* see: http://lists.infradead.org/pipermail/linux-snps-arc/2016-November/001748.html
|
||||
*/
|
||||
static inline void write_aux_reg(u32 r, u32 v)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define READ_BCR(reg, into) \
|
||||
{ \
|
||||
unsigned int tmp; \
|
||||
tmp = read_aux_reg(reg); \
|
||||
if (sizeof(tmp) == sizeof(into)) { \
|
||||
into = *((typeof(into) *)&tmp); \
|
||||
} else { \
|
||||
extern void bogus_undefined(void); \
|
||||
bogus_undefined(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define WRITE_AUX(reg, into) \
|
||||
{ \
|
||||
unsigned int tmp; \
|
||||
if (sizeof(tmp) == sizeof(into)) { \
|
||||
tmp = (*(unsigned int *)&(into)); \
|
||||
write_aux_reg(reg, tmp); \
|
||||
} else { \
|
||||
extern void bogus_undefined(void); \
|
||||
bogus_undefined(); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -8,12 +8,10 @@
|
|||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_MCIP_H
|
||||
#define __ASM_MCIP_H
|
||||
#ifndef __SOC_ARC_MCIP_H
|
||||
#define __SOC_ARC_MCIP_H
|
||||
|
||||
#ifdef CONFIG_ISA_ARCV2
|
||||
|
||||
#include <asm/arcregs.h>
|
||||
#include <soc/arc/aux.h>
|
||||
|
||||
#define ARC_REG_MCIP_BCR 0x0d0
|
||||
#define ARC_REG_MCIP_CMD 0x600
|
||||
|
@ -103,5 +101,3 @@ static inline void __mcip_cmd_data(unsigned int cmd, unsigned int param,
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2016-17 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_ARC_TIMERS_H
|
||||
#define __SOC_ARC_TIMERS_H
|
||||
|
||||
#include <soc/arc/aux.h>
|
||||
|
||||
/* Timer related Aux registers */
|
||||
#define ARC_REG_TIMER0_LIMIT 0x23 /* timer 0 limit */
|
||||
#define ARC_REG_TIMER0_CTRL 0x22 /* timer 0 control */
|
||||
#define ARC_REG_TIMER0_CNT 0x21 /* timer 0 count */
|
||||
#define ARC_REG_TIMER1_LIMIT 0x102 /* timer 1 limit */
|
||||
#define ARC_REG_TIMER1_CTRL 0x101 /* timer 1 control */
|
||||
#define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */
|
||||
|
||||
/* CTRL reg bits */
|
||||
#define TIMER_CTRL_IE (1 << 0) /* Interrupt when Count reaches limit */
|
||||
#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */
|
||||
|
||||
#define ARC_TIMERN_MAX 0xFFFFFFFF
|
||||
|
||||
#define ARC_REG_TIMERS_BCR 0x75
|
||||
|
||||
struct bcr_timer {
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8;
|
||||
#else
|
||||
unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Mellanox Technologies. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SOC_NPS_MTM_H
|
||||
#define SOC_NPS_MTM_H
|
||||
|
||||
#define CTOP_INST_HWSCHD_OFF_R3 0x3B6F00BF
|
||||
#define CTOP_INST_HWSCHD_RESTORE_R3 0x3E6F70C3
|
||||
|
||||
static inline void hw_schd_save(unsigned int *flags)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
" .word %1\n"
|
||||
" st r3,[%0]\n"
|
||||
:
|
||||
: "r"(flags), "i"(CTOP_INST_HWSCHD_OFF_R3)
|
||||
: "r3", "memory");
|
||||
}
|
||||
|
||||
static inline void hw_schd_restore(unsigned int flags)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
" mov r3, %0\n"
|
||||
" .word %1\n"
|
||||
:
|
||||
: "r"(flags), "i"(CTOP_INST_HWSCHD_RESTORE_R3)
|
||||
: "r3");
|
||||
}
|
||||
|
||||
#endif /* SOC_NPS_MTM_H */
|
Loading…
Reference in New Issue