From patchwork Thu Aug 16 06:30:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Simek X-Patchwork-Id: 177910 X-Patchwork-Delegate: albert.aribaud@free.fr Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id A1ED52C007C for ; Thu, 16 Aug 2012 16:31:23 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id E68CD281ED; Thu, 16 Aug 2012 08:31:04 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id jNt8BaQXYWQZ; Thu, 16 Aug 2012 08:31:04 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 978CF2819B; Thu, 16 Aug 2012 08:30:54 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id ED18D281C1 for ; Thu, 16 Aug 2012 08:30:47 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id O8rIeu9GsEFm for ; Thu, 16 Aug 2012 08:30:47 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-we0-f172.google.com (mail-we0-f172.google.com [74.125.82.172]) by theia.denx.de (Postfix) with ESMTPS id 0416F281A3 for ; Thu, 16 Aug 2012 08:30:36 +0200 (CEST) Received: by weyu54 with SMTP id u54so1526665wey.3 for ; Wed, 15 Aug 2012 23:30:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=5LS9aHr3yK4TmMSVZe7wB5WXQZcV7xYg3lxK6VxKxlM=; b=OM2J4/moEFXlvIwQChYLcwqcGhIoPn5eaaMYk59FShuJjTkl9RyomilDmFoLG/2vqz Z1FzpFR8sF7TYvRHwXLyMI2N5BSifcavUQ9KL+ewKmSt4dzsvx+sDffaScwhM4EhJqpR yPF5ZnJYWCW4PcsEMcJiWi8Dj6bOCCj/n9j9+pbMZfbOOd8VCK71xurM4K9eZxAFmjxH nfLo+9cMQEm2Rq6E3LYjbOn5h+NcBEsLwjd74h1Alpf4y8TFhfpC81SAXpCQ7/TuUccx CnqekgfHMRYSTpbz/ohD/YktNhYXrPkCPLTlfXpS/zuaCo6VJorsSKcnAgkYNe5f/K7t hIDA== Received: by 10.180.96.3 with SMTP id do3mr406077wib.5.1345098635927; Wed, 15 Aug 2012 23:30:35 -0700 (PDT) Received: from localhost (nat-2.starnet.cz. [92.62.224.2]) by mx.google.com with ESMTPS id ck9sm3338878wib.2.2012.08.15.23.30.34 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 15 Aug 2012 23:30:35 -0700 (PDT) From: Michal Simek To: u-boot@lists.denx.de, Joe Hershberger Date: Thu, 16 Aug 2012 08:30:29 +0200 Message-Id: <1345098630-27902-3-git-send-email-monstr@monstr.eu> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1345098630-27902-1-git-send-email-monstr@monstr.eu> References: <1345098630-27902-1-git-send-email-monstr@monstr.eu> X-Gm-Message-State: ALoCoQnog29qfeyxZiRSJgGMszY4tDPyEj3lXGxeyqcAm8D4ot/f/6lHLvYfJg+zHTL/1xnCdQxP Subject: [U-Boot] [PATCH 3/4 v2] arm: Support new Xilinx Zynq platform X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Add timer driver. Signed-off-by: Michal Simek --- v2: Move lowlevel_init.S from board to cpu folder Remove XPSS prefix Rename XSCUTIMER -> SCUTIMER Keep timer in zynq folder till ARM custodian comments it. --- arch/arm/cpu/armv7/zynq/Makefile | 52 +++++++++++ arch/arm/cpu/armv7/zynq/lowlevel_init.S | 27 ++++++ arch/arm/cpu/armv7/zynq/timer.c | 151 +++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+), 0 deletions(-) create mode 100644 arch/arm/cpu/armv7/zynq/Makefile create mode 100644 arch/arm/cpu/armv7/zynq/lowlevel_init.S create mode 100644 arch/arm/cpu/armv7/zynq/timer.c diff --git a/arch/arm/cpu/armv7/zynq/Makefile b/arch/arm/cpu/armv7/zynq/Makefile new file mode 100644 index 0000000..1d2d7e1 --- /dev/null +++ b/arch/arm/cpu/armv7/zynq/Makefile @@ -0,0 +1,52 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).o + +SOBJS-y := lowlevel_init.o +COBJS-y := timer.o + +SOBJS := $(SOBJS-y) +COBJS := $(COBJS-y) + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/armv7/zynq/lowlevel_init.S b/arch/arm/cpu/armv7/zynq/lowlevel_init.S new file mode 100644 index 0000000..642eb18 --- /dev/null +++ b/arch/arm/cpu/armv7/zynq/lowlevel_init.S @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2012 Michal Simek + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +ENTRY(lowlevel_init) + mov pc, lr +ENDPROC(lowlevel_init) diff --git a/arch/arm/cpu/armv7/zynq/timer.c b/arch/arm/cpu/armv7/zynq/timer.c new file mode 100644 index 0000000..0252220 --- /dev/null +++ b/arch/arm/cpu/armv7/zynq/timer.c @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2012 Michal Simek + * Copyright (C) 2011-2012 Xilinx, Inc. All rights reserved. + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2003 + * Texas Instruments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct scu_timer { + u32 load; /* Timer Load Register */ + u32 counter; /* Timer Counter Register */ + u32 control; /* Timer Control Register */ +}; + +static struct scu_timer *timer_base = CONFIG_SCUTIMER_BASEADDR; + +#define SCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00 /* Prescaler */ +#define SCUTIMER_CONTROL_PRESCALER_SHIFT 8 +#define SCUTIMER_CONTROL_AUTO_RELOAD_MASK 0x00000002 /* Auto-reload */ +#define SCUTIMER_CONTROL_ENABLE_MASK 0x00000001 /* Timer enable */ + +#define TIMER_LOAD_VAL 0xFFFFFFFF +#define TIMER_PRESCALE 255 +#define TIMER_TICK_HZ (CONFIG_CPU_FREQ_HZ / 2 / TIMER_PRESCALE) + +int timer_init(void) +{ + u32 val; + + /* Load the timer counter register */ + writel(0xFFFFFFFF, &timer_base->counter); + + /* Start the A9Timer device */ + val = readl(&timer_base->control); + /* Enable Auto reload mode */ + val |= SCUTIMER_CONTROL_AUTO_RELOAD_MASK; + /* Clear prescaler control bits */ + val &= ~SCUTIMER_CONTROL_PRESCALER_MASK; + /* Set prescaler value */ + val |= (TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT); + /* Enable the decrementer */ + val |= SCUTIMER_CONTROL_ENABLE_MASK; + writel(val, &timer_base->control); + + /* Reset time */ + gd->lastinc = readl(&timer_base->counter) / + (TIMER_TICK_HZ / CONFIG_SYS_HZ); + gd->tbl = 0; + + return 0; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +ulong get_timer_masked(void) +{ + ulong now; + + now = readl(&timer_base->counter) / (TIMER_TICK_HZ / CONFIG_SYS_HZ); + + if (gd->lastinc >= now) { + /* Normal mode */ + gd->tbl += gd->lastinc - now; + } else { + /* We have an overflow ... */ + gd->tbl += gd->lastinc + TIMER_LOAD_VAL - now; + } + gd->lastinc = now; + + return gd->tbl; +} + +void __udelay(unsigned long usec) +{ + unsigned long long tmp; + ulong tmo; + + tmo = usec / (1000000 / CONFIG_SYS_HZ); + tmp = get_ticks() + tmo; /* Get current timestamp */ + + while (get_ticks() < tmp) { /* Loop till event */ + /* NOP */; + } +} + +/* Timer without interrupts */ +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ; +}