Commit 5cf618ee authored by Tom Rini's avatar Tom Rini

Merge git://git.denx.de/u-boot-arc

This replaces legacy arch/arc/lib/timer.c implementation and allows us
to describe ARC Timers in Device Tree. Among other things that way we
may properly inherit Timer's clock from CPU's clock s they really run
synchronously.
parents c1daa407 3daa7c7b
......@@ -13,6 +13,9 @@ config ARC
select HAVE_PRIVATE_LIBGCC
select SUPPORT_OF_CONTROL
select ARCH_EARLY_INIT_R
select CLK
select TIMER
select ARC_TIMER
config ARM
bool "ARM architecture"
......
......@@ -118,7 +118,7 @@ config SYS_DCACHE_OFF
choice
prompt "Target select"
default TARGET_AXS10X
default TARGET_AXS103
config TARGET_TB100
bool "Support tb100"
......@@ -126,8 +126,11 @@ config TARGET_TB100
config TARGET_NSIM
bool "Support standalone nSIM & Free nSIM"
config TARGET_AXS10X
bool "Support Synopsys Designware SDP board (AXS101 & AXS103)"
config TARGET_AXS101
bool "Support Synopsys Designware SDP board AXS101"
config TARGET_AXS103
bool "Support Synopsys Designware SDP board AXS103"
endchoice
......
......@@ -2,7 +2,8 @@
# SPDX-License-Identifier: GPL-2.0+
#
dtb-$(CONFIG_TARGET_AXS10X) += axs10x.dtb
dtb-$(CONFIG_TARGET_AXS101) += axs101.dtb
dtb-$(CONFIG_TARGET_AXS103) += axs103.dtb
dtb-$(CONFIG_TARGET_NSIM) += nsim.dtb
dtb-$(CONFIG_TARGET_TB100) += abilis_tb100.dtb
......
......@@ -8,13 +8,19 @@
#include "skeleton.dtsi"
/ {
#address-cells = <1>;
#size-cells = <1>;
aliases {
console = &uart0;
};
cpu_card {
core_clk: core_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <500000000>;
u-boot,dm-pre-reloc;
};
};
uart0: serial@ff100000 {
compatible = "snps,dw-apb-uart";
reg = <0xff100000 0x1000>;
......
/*
* Copyright (C) 2017 Synopsys, Inc. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/include/ "skeleton.dtsi"
/ {
cpu_card {
core_clk: core_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <750000000>;
u-boot,dm-pre-reloc;
};
};
};
/*
* Copyright (C) 2017 Synopsys, Inc. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/include/ "skeleton.dtsi"
/ {
cpu_card {
core_clk: core_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <100000000>;
u-boot,dm-pre-reloc;
};
};
};
/*
* Copyright (C) 2017 Synopsys, Inc. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/dts-v1/;
/include/ "axc001.dtsi"
/include/ "axs10x_mb.dtsi"
/ {
chosen {
stdout-path = &uart0;
};
};
/*
* Copyright (C) 2017 Synopsys, Inc. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/dts-v1/;
/include/ "axc003.dtsi"
/include/ "axs10x_mb.dtsi"
/ {
chosen {
stdout-path = &uart0;
};
};
/*
* Copyright (C) 2015 Synopsys, Inc. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/dts-v1/;
#include "skeleton.dtsi"
/ {
#address-cells = <1>;
#size-cells = <1>;
aliases {
console = &uart0;
};
clocks {
apbclk: apbclk {
compatible = "fixed-clock";
clock-frequency = <50000000>;
#clock-cells = <0>;
};
};
uart0: serial0@e0022000 {
compatible = "snps,dw-apb-uart";
reg = <0xe0022000 0x1000>;
reg-shift = <2>;
reg-io-width = <4>;
};
ethernet@e0018000 {
#interrupt-cells = <1>;
compatible = "altr,socfpga-stmmac";
reg = < 0xe0018000 0x2000 >;
interrupts = < 25 >;
interrupt-names = "macirq";
phy-mode = "gmii";
snps,pbl = < 32 >;
clocks = <&apbclk>;
clock-names = "stmmaceth";
max-speed = <100>;
};
ehci@0xe0040000 {
compatible = "generic-ehci";
reg = < 0xe0040000 0x100 >;
interrupts = < 8 >;
};
ohci@0xe0060000 {
compatible = "generic-ohci";
reg = < 0xe0060000 0x100 >;
interrupts = < 8 >;
};
};
/*
* Copyright (C) 2017 Synopsys, Inc. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/ {
axs10x_mb@e0000000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x00000000 0xe0000000 0x10000000>;
u-boot,dm-pre-reloc;
clocks {
compatible = "simple-bus";
u-boot,dm-pre-reloc;
apbclk: apbclk {
compatible = "fixed-clock";
clock-frequency = <50000000>;
#clock-cells = <0>;
};
uartclk: uartclk {
compatible = "fixed-clock";
clock-frequency = <33333333>;
#clock-cells = <0>;
u-boot,dm-pre-reloc;
};
};
ethernet@18000 {
#interrupt-cells = <1>;
compatible = "altr,socfpga-stmmac";
reg = < 0x18000 0x2000 >;
interrupts = < 25 >;
interrupt-names = "macirq";
phy-mode = "gmii";
snps,pbl = < 32 >;
clocks = <&apbclk>;
clock-names = "stmmaceth";
max-speed = <100>;
};
ehci@0x40000 {
compatible = "generic-ehci";
reg = < 0x40000 0x100 >;
interrupts = < 8 >;
};
ohci@0x60000 {
compatible = "generic-ohci";
reg = < 0x60000 0x100 >;
interrupts = < 8 >;
};
uart0: serial0@22000 {
compatible = "snps,dw-apb-uart";
reg = <0x22000 0x100>;
clocks = <&uartclk>;
reg-shift = <2>;
reg-io-width = <4>;
};
};
};
......@@ -8,17 +8,23 @@
#include "skeleton.dtsi"
/ {
#address-cells = <1>;
#size-cells = <1>;
aliases {
console = &arcuart0;
};
cpu_card {
core_clk: core_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <70000000>;
u-boot,dm-pre-reloc;
};
};
arcuart0: serial@0xc0fc1000 {
compatible = "snps,arc-uart";
reg = <0xc0fc1000 0x100>;
clock-frequency = <80000000>;
clock-frequency = <70000000>;
};
};
......@@ -9,5 +9,22 @@
#size-cells = <1>;
chosen { };
aliases { };
memory { device_type = "memory"; reg = <0 0>; };
cpu_card {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
u-boot,dm-pre-reloc;
timer@0 {
compatible = "snps,arc-timer";
clocks = <&core_clk>;
reg = <0 1>;
};
};
memory@80000000 {
device_type = "memory";
reg = <0x80000000 0x10000000>; /* 256M */
};
};
......@@ -33,6 +33,10 @@
#define ARC_AUX_TIMER0_CTRL 0x22 /* Timer 0 control */
#define ARC_AUX_TIMER0_LIMIT 0x23 /* Timer 0 limit */
#define ARC_AUX_TIMER1_CNT 0x100 /* Timer 1 count */
#define ARC_AUX_TIMER1_CTRL 0x101 /* Timer 1 control */
#define ARC_AUX_TIMER1_LIMIT 0x102 /* Timer 1 limit */
#define ARC_AUX_INTR_VEC_BASE 0x25
/* Data cache related auxiliary registers */
......
......@@ -18,7 +18,6 @@ obj-y += memcmp.o
obj-y += memcpy-700.o
obj-y += memset.o
obj-y += reset.o
obj-y += timer.o
obj-y += ints_low.o
obj-y += init_helpers.o
......
/*
* Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm/arcregs.h>
#define NH_MODE (1 << 1) /* Disable timer if CPU is halted */
int timer_init(void)
{
write_aux_reg(ARC_AUX_TIMER0_CTRL, NH_MODE);
/* Set max value for counter/timer */
write_aux_reg(ARC_AUX_TIMER0_LIMIT, 0xffffffff);
/* Set initial count value and restart counter/timer */
write_aux_reg(ARC_AUX_TIMER0_CNT, 0);
return 0;
}
unsigned long timer_read_counter(void)
{
return read_aux_reg(ARC_AUX_TIMER0_CNT);
}
if TARGET_AXS10X
if TARGET_AXS101 || TARGET_AXS103
config SYS_BOARD
default "axs10x"
......
CONFIG_ARC=y
CONFIG_SYS_DCACHE_OFF=y
CONFIG_TARGET_AXS101=y
CONFIG_SYS_TEXT_BASE=0x81000000
CONFIG_SYS_CLK_FREQ=750000000
CONFIG_DEFAULT_DEVICE_TREE="axs10x"
CONFIG_DEFAULT_DEVICE_TREE="axs101"
CONFIG_BOOTDELAY=3
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SYS_PROMPT="AXS# "
......@@ -18,7 +19,6 @@ CONFIG_OF_CONTROL=y
CONFIG_OF_EMBED=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DM=y
CONFIG_CLK=y
CONFIG_SYS_I2C_DW=y
CONFIG_MMC=y
CONFIG_MMC_DW=y
......
......@@ -2,7 +2,7 @@ CONFIG_ARC=y
CONFIG_ISA_ARCV2=y
CONFIG_SYS_TEXT_BASE=0x81000000
CONFIG_SYS_CLK_FREQ=100000000
CONFIG_DEFAULT_DEVICE_TREE="axs10x"
CONFIG_DEFAULT_DEVICE_TREE="axs103"
CONFIG_BOOTDELAY=3
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SYS_PROMPT="AXS# "
......@@ -18,7 +18,6 @@ CONFIG_OF_CONTROL=y
CONFIG_OF_EMBED=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DM=y
CONFIG_CLK=y
CONFIG_SYS_I2C_DW=y
CONFIG_MMC=y
CONFIG_MMC_DW=y
......
ARC Timer
Required properties:
- compatible : should be "snps,arc-timer".
- reg : Specifies timer ID, could be either 0 or 1.
- clocks : Specifies clocks that drives the counter.
Examples:
timer@0 {
compatible = "snps,arc-timer";
clocks = <&core_clk>;
reg = <0>;
};
timer@1 {
compatible = "snps,arc-timer";
clocks = <&core_clk>;
reg = <1>;
};
NOTE: if you specify both timers, clocks always should be the same
as each timer is driven by the same core clock.
......@@ -65,4 +65,13 @@ config STI_TIMER
help
Select this to enable a timer for STi devices.
config ARC_TIMER
bool "ARC timer support"
depends on TIMER && ARC && CLK
help
Select this to enable built-in ARC timers.
ARC cores may have up to 2 built-in timers: timer0 and timer1,
usually at least one of them exists. Either of them is supported
in U-Boot.
endmenu
......@@ -11,3 +11,4 @@ obj-$(CONFIG_X86_TSC_TIMER) += tsc_timer.o
obj-$(CONFIG_OMAP_TIMER) += omap-timer.o
obj-$(CONFIG_AST_TIMER) += ast_timer.o
obj-$(CONFIG_STI_TIMER) += sti-timer.o
obj-$(CONFIG_ARC_TIMER) += arc_timer.o
/*
* Copyright (C) 2016 Synopsys, Inc. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <timer.h>
#include <asm/arcregs.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
#define NH_MODE (1 << 1)
/*
* ARC timer control registers are mapped to auxiliary address space.
* There are special ARC asm command to access that addresses.
* Therefore we use built-in functions to read from and write to timer
* control register.
*/
/* Driver private data. Contains timer id. Could be either 0 or 1. */
struct arc_timer_priv {
uint timer_id;
};
static int arc_timer_get_count(struct udevice *dev, u64 *count)
{
u32 val = 0;
struct arc_timer_priv *priv = dev_get_priv(dev);
switch (priv->timer_id) {
case 0:
val = read_aux_reg(ARC_AUX_TIMER0_CNT);
break;
case 1:
val = read_aux_reg(ARC_AUX_TIMER1_CNT);
break;
}
*count = timer_conv_64(val);
return 0;
}
static int arc_timer_probe(struct udevice *dev)
{
int id;
struct arc_timer_priv *priv = dev_get_priv(dev);
/* Get registers offset and size */
id = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1);
if (id < 0)
return -EINVAL;
if (id > 1)
return -ENXIO;
priv->timer_id = (uint)id;
/*
* In ARC core there're special registers (Auxiliary or AUX) in its
* separate memory space that are used for accessing some hardware
* features of the core. They are not mapped in normal memory space
* and also always have the same location regardless core configuration.
* Thus to simplify understanding of the programming model we chose to
* access AUX regs of Timer0 and Timer1 separately instead of using
* offsets from some base address.
*/
switch (priv->timer_id) {
case 0:
/* Disable timer if CPU is halted */
write_aux_reg(ARC_AUX_TIMER0_CTRL, NH_MODE);
/* Set max value for counter/timer */
write_aux_reg(ARC_AUX_TIMER0_LIMIT, 0xffffffff);
/* Set initial count value and restart counter/timer */
write_aux_reg(ARC_AUX_TIMER0_CNT, 0);
break;
case 1:
/* Disable timer if CPU is halted */
write_aux_reg(ARC_AUX_TIMER1_CTRL, NH_MODE);
/* Set max value for counter/timer */
write_aux_reg(ARC_AUX_TIMER1_LIMIT, 0xffffffff);
/* Set initial count value and restart counter/timer */
write_aux_reg(ARC_AUX_TIMER1_CNT, 0);
break;
}
return 0;
}
static const struct timer_ops arc_timer_ops = {
.get_count = arc_timer_get_count,
};
static const struct udevice_id arc_timer_ids[] = {
{ .compatible = "snps,arc-timer" },
{}
};
U_BOOT_DRIVER(arc_timer) = {
.name = "arc_timer",
.id = UCLASS_TIMER,
.of_match = arc_timer_ids,
.probe = arc_timer_probe,
.ops = &arc_timer_ops,
.flags = DM_FLAG_PRE_RELOC,
.priv_auto_alloc_size = sizeof(struct arc_timer_priv),
};
......@@ -11,8 +11,6 @@
/*
* CPU configuration
*/
#define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ
#define ARC_FPGA_PERIPHERAL_BASE 0xE0000000
#define ARC_APB_PERIPHERAL_BASE 0xF0000000
#define ARC_DWMMC_BASE (ARC_FPGA_PERIPHERAL_BASE + 0x15000)
......
......@@ -9,11 +9,6 @@
#include <linux/sizes.h>
/*
* CPU configuration
*/
#define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ
/*
* Memory configuration
*/
......
......@@ -9,11 +9,6 @@
#include <linux/sizes.h>
/*
* CPU configuration
*/
#define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ
/*
* Memory configuration
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment