[U-Boot] [PATCH] arm926ejs: add NXP LPC32x0 cpu series support
Albert ARIBAUD
albert.u.boot at aribaud.net
Sun Oct 16 18:27:50 CEST 2011
Hi Vladimir,
Le 16/10/2011 18:01, Vladimir Zapolskiy a écrit :
> This change adds initial support for NXP LPC32x0 SoC series.
>
> Signed-off-by: Vladimir Zapolskiy<vz at mleia.com>
> ---
> arch/arm/cpu/arm926ejs/lpc32xx/Makefile | 45 +++++++
> arch/arm/cpu/arm926ejs/lpc32xx/clkpwr.c | 95 ++++++++++++++
> arch/arm/cpu/arm926ejs/lpc32xx/cpu.c | 44 +++++++
> arch/arm/cpu/arm926ejs/lpc32xx/timer.c | 127 +++++++++++++++++++
> arch/arm/include/asm/arch-lpc32xx/clk.h | 156 +++++++++++++++++++++++
> arch/arm/include/asm/arch-lpc32xx/config.h | 39 ++++++
> arch/arm/include/asm/arch-lpc32xx/cpu.h | 65 ++++++++++
> arch/arm/include/asm/arch-lpc32xx/timer.h | 74 +++++++++++
> arch/arm/include/asm/arch-lpc32xx/uart.h | 190 ++++++++++++++++++++++++++++
> arch/arm/include/asm/arch-lpc32xx/wdt.h | 51 ++++++++
> 10 files changed, 886 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/cpu/arm926ejs/lpc32xx/Makefile
> create mode 100644 arch/arm/cpu/arm926ejs/lpc32xx/clkpwr.c
> create mode 100644 arch/arm/cpu/arm926ejs/lpc32xx/cpu.c
> create mode 100644 arch/arm/cpu/arm926ejs/lpc32xx/timer.c
> create mode 100644 arch/arm/include/asm/arch-lpc32xx/clk.h
> create mode 100644 arch/arm/include/asm/arch-lpc32xx/config.h
> create mode 100644 arch/arm/include/asm/arch-lpc32xx/cpu.h
> create mode 100644 arch/arm/include/asm/arch-lpc32xx/timer.h
> create mode 100644 arch/arm/include/asm/arch-lpc32xx/uart.h
> create mode 100644 arch/arm/include/asm/arch-lpc32xx/wdt.h
>
> diff --git a/arch/arm/cpu/arm926ejs/lpc32xx/Makefile b/arch/arm/cpu/arm926ejs/lpc32xx/Makefile
> new file mode 100644
> index 0000000..f2badb6
> --- /dev/null
> +++ b/arch/arm/cpu/arm926ejs/lpc32xx/Makefile
> @@ -0,0 +1,45 @@
> +#
> +# (C) Copyright 2000-2006
> +# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
Are you sure about the date and owner of the copyright?
> +# 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
> +
> +COBJS = cpu.o clkpwr.o timer.o
> +
> +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
> +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
> +
> +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/arm926ejs/lpc32xx/clkpwr.c b/arch/arm/cpu/arm926ejs/lpc32xx/clkpwr.c
> new file mode 100644
> index 0000000..451543b
> --- /dev/null
> +++ b/arch/arm/cpu/arm926ejs/lpc32xx/clkpwr.c
> @@ -0,0 +1,95 @@
> +/*
> + * Copyright (C) 2011 by Vladimir Zapolskiy<vz at mleia.com>
> + *
> + * 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<common.h>
> +#include<div64.h>
> +#include<asm/arch/cpu.h>
> +#include<asm/arch/clk.h>
> +#include<asm/io.h>
> +
> +static clk_t *clk = (clk_t *)CLK_PM_BASE;
> +
> +unsigned int get_sys_clk_rate(void)
> +{
> + if (readl(&clk->sysclk_ctrl)& CLK_SYSCLK_PLL397)
> + return RTC_CLK_FREQUENCY * 397;
> + else
> + return OSC_CLK_FREQUENCY;
> +}
> +
> +unsigned int get_hclk_pll_rate(void)
> +{
> + unsigned long long fin, fref, fcco, fout;
> + u32 val, m_div, n_div, p_div;
> +
> + /*
> + * Valid frequency ranges:
> + * 1 * 10^6<= Fin<= 20 * 10^6
> + * 1 * 10^6<= Fref<= 27 * 10^6
> + * 156 * 10^6<= Fcco<= 320 * 10^6
> + *
> + * Due to these frequency constraints and divider values it could be
> + * shown that 32bit values used here for operations are not overflowed
> + */
> +
> + fref = fin = get_sys_clk_rate();
> + if (fin> 20000000ULL || fin< 1000000ULL)
> + return 0;
> +
> + val = readl(&clk->hclkpll_ctrl);
> + m_div = ((val& CLK_HCLK_PLL_FEEDBACK_DIV_MASK)>> 1) + 1;
> + n_div = ((val& CLK_HCLK_PLL_PREDIV_MASK)>> 9) + 1;
> + if (val& CLK_HCLK_PLL_DIRECT)
> + p_div = 0;
> + else
> + p_div = ((val& CLK_HCLK_PLL_POSTDIV_MASK)>> 11) + 1;
> + p_div = 1<< p_div;
> +
> + if (val& CLK_HCLK_PLL_BYPASS) {
> + do_div(fin, p_div);
> + return fin;
> + }
> +
> + do_div(fref, n_div);
> + if (fref> 27000000ULL || fref< 1000000ULL)
> + return 0;
> +
> + if (val& CLK_HCLK_PLL_FEEDBACK) {
> + fout = fcco = fref * m_div;
> + do_div(fout, p_div);
> + } else {
> + fout = fref * m_div;
> + fcco = fout * p_div;
> + }
> +
> + if (fcco> 320000000ULL || fcco< 156000000ULL)
> + return 0;
> +
> + return fout;
> +}
> +
> +unsigned int get_periph_clk_rate(void)
> +{
> + u32 val;
> +
> + if (!(readl(&clk->pwr_ctrl)& CLK_PWR_NORMAL_RUN))
> + return get_sys_clk_rate();
> +
> + val = (readl(&clk->hclkdiv_ctrl)& CLK_HCLK_PERIPH_DIV_MASK)>> 2;
> + return get_hclk_pll_rate() / (val + 1);
> +}
> diff --git a/arch/arm/cpu/arm926ejs/lpc32xx/cpu.c b/arch/arm/cpu/arm926ejs/lpc32xx/cpu.c
> new file mode 100644
> index 0000000..1f6c964
> --- /dev/null
> +++ b/arch/arm/cpu/arm926ejs/lpc32xx/cpu.c
> @@ -0,0 +1,44 @@
> +/*
> + * Copyright (C) 2011 by Vladimir Zapolskiy<vz at mleia.com>
> + *
> + * 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<common.h>
> +#include<asm/arch/cpu.h>
> +#include<asm/arch/clk.h>
> +#include<asm/arch/wdt.h>
> +#include<asm/io.h>
> +
> +void reset_cpu(ulong addr)
> +{
> + clk_t *clk = (clk_t *)CLK_PM_BASE;
> + wdtim_t *wdt = (wdtim_t *)WDT_BASE;
> + u32 val;
> +
> + /* Enable watchdog clock */
> + val = readl(&clk->timclk_ctrl);
> + writel(val | CLKPWR_TIMCLK_WATCHDOG,&clk->timclk_ctrl);
> +
> + /* Reset pulse length is 13005 PERIPH_CLKs */
> + writel(13000,&wdt->pulse);
> +
> + /* Force WDOG_RESET2 and RESOUT_N signal active */
> + writel(WDTIM_MCTRL_RESFRC2 | WDTIM_MCTRL_RESFRC1 | WDTIM_MCTRL_M_RES2,
> + &wdt->mctrl);
> +
> + while (1) {}
> +}
> diff --git a/arch/arm/cpu/arm926ejs/lpc32xx/timer.c b/arch/arm/cpu/arm926ejs/lpc32xx/timer.c
> new file mode 100644
> index 0000000..4563ee9
> --- /dev/null
> +++ b/arch/arm/cpu/arm926ejs/lpc32xx/timer.c
> @@ -0,0 +1,127 @@
> +/*
> + * Copyright (C) 2011 Vladimir Zapolskiy<vz at mleia.com>
> + *
> + * 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<common.h>
> +#include<asm/arch/cpu.h>
> +#include<asm/arch/clk.h>
> +#include<asm/arch/timer.h>
> +#include<asm/io.h>
> +
> +static timer_t *timer0 = (timer_t *)TIMER0_BASE;
> +static timer_t *timer1 = (timer_t *)TIMER1_BASE;
> +static clk_t *clk = (clk_t *)CLK_PM_BASE;
> +
> +static void lpc32xx_timer_clock(u32 bit, int enable)
> +{
> + u32 val = readl(&clk->timclk_ctrl1);
> +
> + if (enable)
> + val |= bit;
> + else
> + val&= ~bit;
> +
> + writel(val,&clk->timclk_ctrl1);
> +}
> +
> +static void lpc32xx_timer_setup_interrupt(timer_t *timer, int match, int count)
> +{
> + /* match should be in range 0..4 */
> +
> + /* Clear match interrupt */
> + writel(TIMER_IR_MR(match),&timer->ir);
> +
> + /* Set match count */
> + writel(count,&timer->mr[match]);
> +
> + /* Interrupt on match */
> + writel(TIMER_MCR_INTERRUPT(match),&timer->mcr);
> +
> +}
> +
> +static void lpc32xx_timer_wait_for_interrupt(timer_t *timer, int match)
> +{
> + /* Loop until interrupt happens */
> + while (!(readl(&timer->ir)& TIMER_IR_MR(match))) {}
> +}
> +
> +static void lpc32xx_timer_reset(timer_t *timer, u32 freq)
> +{
> + /* Reset timer */
> + writel(TIMER_TCR_COUNTER_RESET,&timer->tcr);
> + writel(TIMER_TCR_COUNTER_DISABLE,&timer->tcr);
> + writel(0,&timer->tc);
> + writel(0,&timer->pr);
> +
> +#if defined(EXPERIMENTAL)
> + /* Clear match */
> + writel(TIMER_IR_MR(0),&timer->ir);
> +#endif
> +
> + /* Count mode is every rising PCLK edge */
> + writel(TIMER_CTCR_MODE_TIMER,&timer->ctcr);
> +
> + /* Set prescale counter value */
> + writel((get_periph_clk_rate() / freq) - 1,&timer->pr);
> +}
> +
> +static void lpc32xx_timer_count(timer_t *timer, int enable)
> +{
> + if (enable)
> + writel(TIMER_TCR_COUNTER_ENABLE,&timer->tcr);
> + else
> + writel(TIMER_TCR_COUNTER_DISABLE,&timer->tcr);
> +}
> +
> +void reset_timer(void)
> +{
> + lpc32xx_timer_reset(timer0, CONFIG_SYS_HZ);
> + lpc32xx_timer_count(timer0, 1);
> +}
Do we need a reset_timer? I was under the impression that we should
never reset any timer in U-Boot.
> +int timer_init(void)
> +{
> + lpc32xx_timer_clock(CLKPWR_TIMCLK_TIMER0, 1);
> + reset_timer();
> +
> + return 0;
> +}
> +
> +ulong get_timer(ulong base)
> +{
> + return readl(&timer0->tc) - base;
> +}
> +
> +void __udelay(unsigned long usec)
> +{
> + lpc32xx_timer_clock(CLKPWR_TIMCLK_TIMER1, 1);
> + lpc32xx_timer_reset(timer1, CONFIG_SYS_HZ * 1000);
> +
> + lpc32xx_timer_setup_interrupt(timer1, 0, usec);
> + lpc32xx_timer_count(timer1, 1);
> +
> + lpc32xx_timer_wait_for_interrupt(timer1, 0);
> +
> + lpc32xx_timer_count(timer1, 0);
> + lpc32xx_timer_clock(CLKPWR_TIMCLK_TIMER1, 0);
> +}
Do you need interrupts to get udelay() working?
> +ulong get_tbclk(void)
> +{
> + return CONFIG_SYS_HZ;
> +}
> diff --git a/arch/arm/include/asm/arch-lpc32xx/clk.h b/arch/arm/include/asm/arch-lpc32xx/clk.h
> new file mode 100644
> index 0000000..506bf43
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-lpc32xx/clk.h
> @@ -0,0 +1,156 @@
> +/*
> + * Copyright (C) 2011 by Vladimir Zapolskiy<vz at mleia.com>
> + *
> + * 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
> + */
> +
> +#ifndef _LPC32XX_CLK_H
> +#define _LPC32XX_CLK_H
> +
> +#include<asm/types.h>
> +#include<asm/arch/cpu.h>
> +
> +#define OSC_CLK_FREQUENCY 13000000
> +#define RTC_CLK_FREQUENCY 32768
> +
> +/* Clocking and Power Control Registers */
> +typedef struct {
> + u32 reserved0[5];
> + u32 boot_map; /* Boot Map Control Register */
> + u32 p0_intr_er; /* Port 0/1 Start and interrupt Enable Register */
> + u32 usbdiv_ctrl; /* USB Clock Pre-Divide Register */
> + /* Internal Start Signal Sources Registers */
> + u32 start_er_int; /* Start Enable Register */
> + u32 start_rsr_int; /* Start Raw Status Register */
> + u32 start_sr_int; /* Start Status Register */
> + u32 start_apr_int; /* Start Activation Polarity Register */
> + /* Device Pin Start Signal Sources Registers */
> + u32 start_er_pin; /* Start Enable Register */
> + u32 start_rsr_pin; /* Start Raw Status Register */
> + u32 start_sr_pin; /* Start Status Register */
> + u32 start_apr_pin; /* Start Activation Polarity Register */
> + /* Clock Control Registers */
> + u32 hclkdiv_ctrl; /* HCLK Divider Control Register */
> + u32 pwr_ctrl; /* Power Control Register */
> + u32 pll397_ctrl; /* PLL397 Control Register */
> + u32 osc_ctrl; /* Main Oscillator Control Register */
> + u32 sysclk_ctrl; /* SYSCLK Control Register */
> + u32 lcdclk_ctrl; /* LCD Clock Control Register */
> + u32 hclkpll_ctrl; /* HCLK PLL Control Register */
> + u32 reserved1;
> + u32 adclk_ctrl1; /* ADC Clock Control1 Register */
> + u32 usb_ctrl; /* USB Control Register */
> + u32 sdramclk_ctrl; /* SDRAM Clock Control Register */
> + u32 ddr_lap_nom; /* DDR Calibration Nominal Value */
> + u32 ddr_lap_count; /* DDR Calibration Measured Value */
> + u32 ddr_cal_delay; /* DDR Calibration Delay Value */
> + u32 ssp_ctrl; /* SSP Control Register */
> + u32 i2s_ctrl; /* I2S Clock Control Register */
> + u32 ms_ctrl; /* Memory Card Control Register */
> + u32 reserved2[3];
> + u32 macclk_ctrl; /* Ethernet MAC Clock Control Register */
> + u32 reserved3[4];
> + u32 test_clk; /* Test Clock Selection Register */
> + u32 sw_int; /* Software Interrupt Register */
> + u32 i2cclk_ctrl; /* I2C Clock Control Register */
> + u32 keyclk_ctrl; /* Keyboard Scan Clock Control Register */
> + u32 adclk_ctrl; /* ADC Clock Control Register */
> + u32 pwmclk_ctrl; /* PWM Clock Control Register */
> + u32 timclk_ctrl; /* Timer Clock Control Register */
> + u32 timclk_ctrl1; /* Timer Clock Control1 and MCPWM Register */
> + u32 spi_ctrl; /* SPI Control Register */
> + u32 flashclk_ctrl; /* NAND Flash Clock Control Register */
> + u32 reserved4;
> + u32 u3clk; /* UART 3 Clock Control Register */
> + u32 u4clk; /* UART 4 Clock Control Register */
> + u32 u5clk; /* UART 5 Clock Control Register */
> + u32 u6clk; /* UART 6 Clock Control Register */
> + u32 irdaclk; /* IrDA Clock Control Register */
> + u32 uartclk_ctrl; /* UART Clock Control Register */
> + u32 dmaclk_ctrl; /* DMA Clock Control Register */
> + u32 autoclk_ctrl; /* Autoclock Control Register */
> +} clk_t;
> +
> +/* HCLK Divider Control Register bits */
> +#define CLK_HCLK_DDRAM_HALF SBF(7, 0x2)
> +#define CLK_HCLK_DDRAM_NOMINAL SBF(7, 0x1)
> +#define CLK_HCLK_DDRAM_STOPPED SBF(7, 0x0)
> +#define CLK_HCLK_PERIPH_DIV_MASK SBF(2, 0x1F)
> +#define CLK_HCLK_PERIPH_DIV(n) SBF(2, (n - 1)& 0x1F)
> +#define CLK_HCLK_ARM_PLL_DIV_4 SBF(0, 0x2)
> +#define CLK_HCLK_ARM_PLL_DIV_2 SBF(0, 0x1)
> +#define CLK_HCLK_ARM_PLL_DIV_1 SBF(0, 0x0)
> +
> +/* Power Control Register bits */
> +#define CLK_PWR_HCLK_RUN_PERIPH BIT(10)
> +#define CLK_PWR_EMC_SREFREQ BIT(9)
> +#define CLK_PWR_EMC_SREFREQ_UPDATE BIT(8)
> +#define CLK_PWR_SDRAM_SREFREQ BIT(7)
> +#define CLK_PWR_HIGHCORE_LEVEL BIT(5)
> +#define CLK_PWR_SYSCLKEN_LEVEL BIT(4)
> +#define CLK_PWR_SYSCLKEN_CTRL BIT(3)
> +#define CLK_PWR_NORMAL_RUN BIT(2)
> +#define CLK_PWR_HIGHCORE_CTRL BIT(1)
> +#define CLK_PWR_STOP_MODE BIT(0)
> +
> +/* SYSCLK Control Register bits */
> +#define CLK_SYSCLK_PLL397 BIT(1)
> +#define CLK_SYSCLK_MUX BIT(0)
> +
> +/* HCLK PLL Control Register bits */
> +#define CLK_HCLK_PLL_OPERATING BIT(16)
> +#define CLK_HCLK_PLL_BYPASS BIT(15)
> +#define CLK_HCLK_PLL_DIRECT BIT(14)
> +#define CLK_HCLK_PLL_FEEDBACK BIT(13)
> +#define CLK_HCLK_PLL_POSTDIV_MASK SBF(11, 0x3)
> +#define CLK_HCLK_PLL_POSTDIV_16 SBF(11, 0x3)
> +#define CLK_HCLK_PLL_POSTDIV_8 SBF(11, 0x2)
> +#define CLK_HCLK_PLL_POSTDIV_4 SBF(11, 0x1)
> +#define CLK_HCLK_PLL_POSTDIV_2 SBF(11, 0x0)
> +#define CLK_HCLK_PLL_PREDIV_MASK SBF(9, 0x3)
> +#define CLK_HCLK_PLL_PREDIV_4 SBF(9, 0x3)
> +#define CLK_HCLK_PLL_PREDIV_3 SBF(9, 0x2)
> +#define CLK_HCLK_PLL_PREDIV_2 SBF(9, 0x1)
> +#define CLK_HCLK_PLL_PREDIV_1 SBF(9, 0x0)
> +#define CLK_HCLK_PLL_FEEDBACK_DIV_MASK SBF(1, 0xFF)
> +#define CLK_HCLK_PLL_FEEDBACK_DIV(n) SBF(1, (n - 1)& 0xFF)
> +#define CLK_HCLK_PLL_LOCKED BIT(0)
> +
> +/* Timer Clock Control1 Register bits */
> +#define CLKPWR_TIMCLK_MOTOR BIT(5)
> +#define CLKPWR_TIMCLK_TIMER3 BIT(5)
> +#define CLKPWR_TIMCLK_TIMER2 BIT(4)
> +#define CLKPWR_TIMCLK_TIMER1 BIT(3)
> +#define CLKPWR_TIMCLK_TIMER0 BIT(2)
> +#define CLKPWR_TIMCLK_TIMER5 BIT(1)
> +#define CLKPWR_TIMCLK_TIMER4 BIT(0)
> +
> +/* Timer Clock Control Register bits */
> +#define CLKPWR_TIMCLK_HSTIMER BIT(1)
> +#define CLKPWR_TIMCLK_WATCHDOG BIT(0)
> +
> +/* UART Clock Control Register bits */
> +#define CLKPWR_UART(n) BIT((n) - 3)
> +
> +/* UARTn Clock Select Registers bits */
> +#define CLKPWR_UART_HCLK BIT(16)
> +#define CLKPWR_UART_X_DIV(n) SBF(8, (n)& 0xFF)
> +#define CLKPWR_UART_Y_DIV(n) SBF(0, (n)& 0xFF)
> +
> +unsigned int get_sys_clk_rate(void);
> +unsigned int get_hclk_pll_rate(void);
> +unsigned int get_periph_clk_rate(void);
> +
> +#endif /* _LPC32XX_CLK_H */
> diff --git a/arch/arm/include/asm/arch-lpc32xx/config.h b/arch/arm/include/asm/arch-lpc32xx/config.h
> new file mode 100644
> index 0000000..9ecdcc9
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-lpc32xx/config.h
> @@ -0,0 +1,39 @@
> +/*
> + * (C) Copyright 2011 by Vladimir Zapolskiy<vz at mleia.com>
> + *
> + * 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., 51 Franklin Street, Fifth Floor, Boston,
> + * MA 02110-1301 USA
> + */
> +
> +/*
> + * This file should be included in board config header file.
> + *
> + * It supports common definitions for LPC32XX platforms
> + */
> +
> +#ifndef _LPC32XX_CONFIG_H
> +#define _LPC32XX_CONFIG_H
> +
> +#define CONFIG_ARM926EJS 1 /* Basic Architecture */
> +
> +#define CONFIG_NR_DRAM_BANKS_MAX 2
> +
> +/* 1KHz clock tick */
> +#define CONFIG_SYS_HZ 1000
> +
> +#endif /* _LPC32XX_CONFIG_H */
> diff --git a/arch/arm/include/asm/arch-lpc32xx/cpu.h b/arch/arm/include/asm/arch-lpc32xx/cpu.h
> new file mode 100644
> index 0000000..b66e221
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-lpc32xx/cpu.h
> @@ -0,0 +1,65 @@
> +/*
> + * Copyright (C) 2011 by Vladimir Zapolskiy<vz at mleia.com>
> + *
> + * 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
> + */
> +
> +#ifndef _LPC32XX_CPU_H
> +#define _LPC32XX_CPU_H
> +
> +#define SBF(s, v) (((unsigned long)(v))<< (s))
> +#define BIT(b) SBF(b, 0x01)
Those names are not really self-explanatory.
Besides, I don't think a macro is justified for just shifting values --
I prefer the shift to be explicit, or even to be precomputed.
> +/* LPC32XX Memory map */
> +
> +/* AHB physical base addresses */
> +#define SLC_NAND_BASE 0x20020000 /* SLC NAND Flash registers base */
> +#define SSP0_BASE 0x20084000 /* SSP0 registers base */
> +#define SD_CARD_BASE 0x20098000 /* SD card interface registers base */
> +#define MLC_NAND_BASE 0x200A8000 /* MLC NAND Flash registers base */
> +#define DMA_BASE 0x31000000 /* DMA controller registers base */
> +#define USB_BASE 0x31020000 /* USB registers base */
> +#define ETHERNET_BASE 0x31060000 /* Ethernet registers base */
> +#define EMC_BASE 0x31080000 /* EMC configuration registers base */
> +
> +/* FAB peripherals base addresses */
> +#define CLK_PM_BASE 0x40004000 /* System control registers base */
> +#define HS_UART1_BASE 0x40014000 /* High speed UART 1 registers base */
> +#define HS_UART2_BASE 0x40018000 /* High speed UART 2 registers base */
> +#define HS_UART7_BASE 0x4001C000 /* High speed UART 7 registers base */
> +#define GPIO_BASE 0x40028000 /* GPIO registers base */
> +#define WDT_BASE 0x4003C000 /* Watchdog timer registers base */
> +#define TIMER0_BASE 0x40044000 /* Timer0 registers base */
> +#define TIMER1_BASE 0x4004C000 /* Timer1 registers base */
> +#define UART_CTRL_BASE 0x40054000 /* UART control regsisters base */
> +
> +/* APB peripherals base addresses */
> +#define UART3_BASE 0x40080000 /* UART 3 registers base */
> +#define UART4_BASE 0x40088000 /* UART 4 registers base */
> +#define UART5_BASE 0x40090000 /* UART 5 registers base */
> +#define UART6_BASE 0x40098000 /* UART 6 registers base */
> +
> +/* External SDRAM Memory Bank base addresses */
> +#define EMC_DYCS0_BASE 0x80000000 /* SDRAM DYCS0 base address */
> +#define EMC_DYCS1_BASE 0xA0000000 /* SDRAM DYCS1 base address */
> +
> +/* External Static Memory Bank base addresses */
> +#define EMC_CS0_BASE 0xE0000000
> +#define EMC_CS1_BASE 0xE1000000
> +#define EMC_CS2_BASE 0xE2000000
> +#define EMC_CS3_BASE 0xE3000000
> +
> +#endif /* _LPC32XX_CPU_H */
> diff --git a/arch/arm/include/asm/arch-lpc32xx/timer.h b/arch/arm/include/asm/arch-lpc32xx/timer.h
> new file mode 100644
> index 0000000..de5e84c
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-lpc32xx/timer.h
> @@ -0,0 +1,74 @@
> +/*
> + * Copyright (C) 2011 by Vladimir Zapolskiy<vz at mleia.com>
> + *
> + * 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
> + */
> +
> +#ifndef _LPC32XX_TIMER_H
> +#define _LPC32XX_TIMER_H
> +
> +#include<asm/types.h>
> +
> +/* Timer/Counter Registers */
> +typedef struct {
> + u32 ir; /* Interrupt Register */
> + u32 tcr; /* Timer Control Register */
> + u32 tc; /* Timer Counter */
> + u32 pr; /* Prescale Register */
> + u32 pc; /* Prescale Counter */
> + u32 mcr; /* Match Control Register */
> + u32 mr[4]; /* Match Registers */
> + u32 ccr; /* Capture Control Register */
> + u32 cr[4]; /* Capture Registers */
> + u32 emr; /* External Match Register */
> + u32 reserved[12];
> + u32 ctcr; /* Count Control Register */
> +} timer_t;
> +
> +/* Timer/Counter Interrupt Register bits */
> +#define TIMER_IR_CR(n) BIT((n) + 4)
> +#define TIMER_IR_MR(n) BIT((n))
> +
> +/* Timer/Counter Timer Control Register bits */
> +#define TIMER_TCR_COUNTER_RESET BIT(1)
> +#define TIMER_TCR_COUNTER_ENABLE BIT(0)
> +#define TIMER_TCR_COUNTER_DISABLE 0x0000
> +
> +/* Timer/Counter Match Control Register bits */
> +#define TIMER_MCR_STOP(n) BIT(3 * (n) + 2)
> +#define TIMER_MCR_RESET(n) BIT(3 * (n) + 1)
> +#define TIMER_MCR_INTERRUPT(n) BIT(3 * (n))
> +
> +/* Timer/Counter Capture Control Register bits */
> +#define TIMER_CCR_INTERRUPT(n) BIT(3 * (n) + 2)
> +#define TIMER_CCR_FALLING_EDGE(n) BIT(3 * (n) + 1)
> +#define TIMER_CCR_RISING_EDGE(n) BIT(3 * (n))
> +
> +/* Timer/Counter External Match Register bits */
> +#define TIMER_EMR_EMC_TOGGLE(n) SBF(2 * (n) + 4, 0x3)
> +#define TIMER_EMR_EMC_SET(n) SBF(2 * (n) + 4, 0x2)
> +#define TIMER_EMR_EMC_CLEAR(n) SBF(2 * (n) + 4, 0x1)
> +#define TIMER_EMR_EMC_NOTHING(n) SBF(2 * (n) + 4, 0x0)
> +#define TIMER_EMR_EM(n) BIT((n))
> +
> +/* Timer/Counter Count Control Register bits */
> +#define TIMER_CTCR_INPUT(n) SBF(2, (n))
> +#define TIMER_CTCR_MODE_COUNTER_BOTH SBF(0, 0x3)
> +#define TIMER_CTCR_MODE_COUNTER_FALLING SBF(0, 0x2)
> +#define TIMER_CTCR_MODE_COUNTER_RISING SBF(0, 0x1)
> +#define TIMER_CTCR_MODE_TIMER SBF(0, 0x0)
> +
> +#endif /* _LPC32XX_TIMER_H */
> diff --git a/arch/arm/include/asm/arch-lpc32xx/uart.h b/arch/arm/include/asm/arch-lpc32xx/uart.h
> new file mode 100644
> index 0000000..4a55eb9
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-lpc32xx/uart.h
> @@ -0,0 +1,190 @@
> +/*
> + * Copyright (C) 2011 by Vladimir Zapolskiy<vz at mleia.com>
> + *
> + * 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
> + */
> +
> +#ifndef _LPC32XX_UART_H
> +#define _LPC32XX_UART_H
> +
> +#include<asm/types.h>
> +
> +/* Standard UART Registers */
> +typedef struct {
> + union {
> + u32 rbr; /* Receiver Buffer Register */
> + u32 thr; /* Transmit Holding Register */
> + u32 dll; /* Divisor Latch Lower Byte */
> + };
> + union {
> + u32 dlm; /* Divisor Latch Higher Byte */
> + u32 ier; /* Interrupt Enable Register */
> + };
> + union {
> + u32 iir; /* Interrupt ID Register */
> + u32 fcr; /* FIFO Control Register */
> + };
> + u32 lcr; /* Line Control Register */
> + u32 mcr; /* Modem Control Register */
> + u32 lsr; /* Line Status Register */
> + u32 msr; /* Modem Status Register */
> + u32 rxlev; /* Receive FIFO Level Register */
> +} uart_t;
>
Isn't this a 16550? If so, you should ise the existing 16550 driver.
> +/* UART Interrupt Enable Register bits */
> +#define UART_IER_MODEM_STATUS BIT(3)
> +#define UART_IER_RX_LINE_STATUS BIT(2)
> +#define UART_IER_THRE BIT(1)
> +#define UART_IER_RDA BIT(0)
> +
> +/* UART Interrupt Identification Register bits */
> +#define UART_IIR_FIFO_ENABLE SBF(6, 0x0)
> +#define UART_IIR_ID_MASK SBF(1, 0x7)
> +#define UART_IIR_ID_CTI SBF(1, 0x6)
> +#define UART_IIR_ID_RLS SBF(1, 0x3)
> +#define UART_IIR_ID_RDA SBF(1, 0x2)
> +#define UART_IIR_ID_THR SBF(1, 0x1)
> +#define UART_IIR_ID_MS SBF(1, 0x0)
> +#define UART_IIR_nPENDING BIT(0)
> +
> +/* UART FIFO Control Register bits */
> +#define UART_FCR_RX_TL60 SBF(6, 0x3)
> +#define UART_FCR_RX_TL48 SBF(6, 0x2)
> +#define UART_FCR_RX_TL32 SBF(6, 0x1)
> +#define UART_FCR_RX_TL16 SBF(6, 0x0)
> +#define UART_FCR_TX_TL16 SBF(4, 0x3)
> +#define UART_FCR_TX_TL8 SBF(4, 0x2)
> +#define UART_FCR_TX_TL4 SBF(4, 0x1)
> +#define UART_FCR_TX_TL0 SBF(4, 0x0)
> +#define UART_FCR_FIFO_CONTROL BIT(3)
> +#define UART_FCR_TX_RESET BIT(2)
> +#define UART_FCR_RX_RESET BIT(1)
> +#define UART_FCR_FIFO_ENABLE BIT(0)
> +
> +/* UART Line Control Register bits */
> +#define UART_LCR_DLA BIT(7)
> +#define UART_LCR_BREAK BIT(6)
> +#define UART_LCR_PARITY_0 SBF(4, 0x3)
> +#define UART_LCR_PARITY_1 SBF(4, 0x2)
> +#define UART_LCR_PARITY_EVEN SBF(4, 0x1)
> +#define UART_LCR_PARITY_ODD SBF(4, 0x0)
> +#define UART_LCR_PARITY_ENABLE BIT(3)
> +#define UART_LCR_STOPBIT_2 BIT(2)
> +#define UART_LCR_WORD_8BIT SBF(0, 0x3)
> +#define UART_LCR_WORD_7BIT SBF(0, 0x2)
> +#define UART_LCR_WORD_6BIT SBF(0, 0x1)
> +#define UART_LCR_WORD_5BIT SBF(0, 0x0)
> +
> +/* UART Line Status Register bits */
> +#define UART_LSR_RX_ERROR BIT(7)
> +#define UART_LSR_TEMT BIT(6)
> +#define UART_LSR_THRE BIT(5)
> +#define UART_LSR_BI BIT(4)
> +#define UART_LSR_FE BIT(3)
> +#define UART_LSR_PE BIT(2)
> +#define UART_LSR_OE BIT(1)
> +#define UART_LSR_RDR BIT(0)
> +
> +/* 14-clock UART Registers */
14-clock? What does that mean?
> +typedef struct {
> + union {
> + u32 rx; /* Receiver FIFO */
> + u32 tx; /* Transmitter FIFO */
> + };
> + u32 level; /* FIFO Level Register */
> + u32 iir; /* Interrupt ID Register */
> + u32 ctrl; /* Control Register */
> + u32 rate; /* Rate Control Register */
> +} hsuart_t;
> +
> +/* 14-clock UART Receiver FIFO Register bits */
> +#define HSUART_RX_BREAK BIT(10)
> +#define HSUART_RX_ERROR BIT(9)
> +#define HSUART_RX_EMPTY BIT(8)
> +#define HSUART_RX_DATA SBF(0, 0xff)
> +
> +/* 14-clock UART Level Register bits */
> +#define HSUART_LEVEL_TX SBF(8, 0xff)
> +#define HSUART_LEVEL_RX SBF(0, 0xff)
> +
> +/* 14-clock UART Interrupt Identification Register bits */
> +#define HSUART_IIR_TX_INTERRUPT_SET BIT(6)
> +#define HSUART_IIR_RX_OVERRUN BIT(5)
> +#define HSUART_IIR_BREAK BIT(4)
> +#define HSUART_IIR_FRAMING BIT(3)
> +#define HSUART_IIR_RX_TIMEOUT BIT(2)
> +#define HSUART_IIR_RX_TRIG BIT(1)
> +#define HSUART_IIR_TX BIT(0)
> +
> +/* 14-clock UART Control Register bits */
> +#define HSUART_CTRL_HRTS_INV BIT(21)
> +#define HSUART_CTRL_HRTS_TRIG_48 SBF(19, 0x3)
> +#define HSUART_CTRL_HRTS_TRIG_32 SBF(19, 0x2)
> +#define HSUART_CTRL_HRTS_TRIG_16 SBF(19, 0x1)
> +#define HSUART_CTRL_HRTS_TRIG_8 SBF(19, 0x0)
> +#define HSUART_CTRL_HRTS_EN BIT(18)
> +#define HSUART_CTRL_TMO_16 SBF(16, 0x3)
> +#define HSUART_CTRL_TMO_8 SBF(16, 0x2)
> +#define HSUART_CTRL_TMO_4 SBF(16, 0x1)
> +#define HSUART_CTRL_TMO_DISABLED SBF(16, 0x0)
> +#define HSUART_CTRL_HCTS_INV BIT(15)
> +#define HSUART_CTRL_HCTS_EN BIT(14)
> +#define HSUART_CTRL_HSU_OFFSET(n) SBF(9, (n))
> +#define HSUART_CTRL_HSU_BREAK BIT(8)
> +#define HSUART_CTRL_HSU_ERR_INT_EN BIT(7)
> +#define HSUART_CTRL_HSU_RX_INT_EN BIT(6)
> +#define HSUART_CTRL_HSU_TX_INT_EN BIT(5)
> +#define HSUART_CTRL_HSU_RX_TRIG_48 SBF(2, 0x5)
> +#define HSUART_CTRL_HSU_RX_TRIG_32 SBF(2, 0x4)
> +#define HSUART_CTRL_HSU_RX_TRIG_16 SBF(2, 0x3)
> +#define HSUART_CTRL_HSU_RX_TRIG_8 SBF(2, 0x2)
> +#define HSUART_CTRL_HSU_RX_TRIG_4 SBF(2, 0x1)
> +#define HSUART_CTRL_HSU_RX_TRIG_1 SBF(2, 0x0)
> +#define HSUART_CTRL_HSU_TX_TRIG_16 SBF(0, 0x3)
> +#define HSUART_CTRL_HSU_TX_TRIG_8 SBF(0, 0x2)
> +#define HSUART_CTRL_HSU_TX_TRIG_4 SBF(0, 0x1)
> +#define HSUART_CTRL_HSU_TX_TRIG_0 SBF(0, 0x0)
> +
> +/* UART Control Registers */
> +typedef struct {
> + u32 ctrl; /* Control Register */
> + u32 clkmode; /* Clock Mode Register */
> + u32 loop; /* Loopback Control Register */
> +} uart_control_t;
> +
> +/* UART Control Register bits */
> +#define UART_CTRL_UART3_MD_CTRL BIT(11)
> +#define UART_CTRL_HDPX_INV BIT(10)
> +#define UART_CTRL_HDPX_EN BIT(9)
> +#define UART_CTRL_UART6_IRDA BIT(5)
> +#define UART_CTRL_IR_TX6_INV BIT(4)
> +#define UART_CTRL_IR_RX6_INV BIT(3)
> +#define UART_CTRL_IR_RX_LENGTH BIT(2)
> +#define UART_CTRL_IR_TX_LENGTH BIT(1)
> +#define UART_CTRL_UART5_USB_MODE BIT(0)
> +
> +/* UART Clock Mode Register bits */
> +#define UART_CLKMODE_STATX(n) BIT((n) + 16)
> +#define UART_CLKMODE_STAT BIT(14)
> +#define UART_CLKMODE_MASK(n) SBF(2 * (n) - 2, 0x3)
> +#define UART_CLKMODE_AUTO(n) SBF(2 * (n) - 2, 0x2)
> +#define UART_CLKMODE_ON(n) SBF(2 * (n) - 2, 0x1)
> +#define UART_CLKMODE_OFF(n) SBF(2 * (n) - 2, 0x0)
> +
> +/* UART Loopback Control Register bits */
> +#define UART_LOOPBACK(n) BIT((n) - 1)
> +
> +#endif /* _LPC32XX_UART_H */
> diff --git a/arch/arm/include/asm/arch-lpc32xx/wdt.h b/arch/arm/include/asm/arch-lpc32xx/wdt.h
> new file mode 100644
> index 0000000..670ba01
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-lpc32xx/wdt.h
> @@ -0,0 +1,51 @@
> +/*
> + * Copyright (C) 2011 by Vladimir Zapolskiy<vz at mleia.com>
> + *
> + * 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
> + */
> +
> +#ifndef _LPC32XX_WDT_H
> +#define _LPC32XX_WDT_H
> +
> +#include<asm/types.h>
> +
> +/* Watchdog Timer Registers */
> +typedef struct {
> + u32 isr; /* Interrupt Status Register */
> + u32 ctrl; /* Control Register */
> + u32 counter; /* Counter Value Register */
> + u32 mctrl; /* Match Control Register */
> + u32 match0; /* Match 0 Register */
> + u32 emr; /* External Match Control Register */
> + u32 pulse; /* Reset Pulse Length Register */
> + u32 res; /* Reset Source Register */
> +} wdtim_t;
> +
> +/* Watchdog Timer Control Register bits */
> +#define WDTIM_CTRL_PAUSE_EN BIT(2)
> +#define WDTIM_CTRL_RESET_COUNT BIT(1)
> +#define WDTIM_CTRL_COUNT_ENAB BIT(0)
> +
> +/* Watchdog Timer Match Control Register bits */
> +#define WDTIM_MCTRL_RESFRC2 BIT(6)
> +#define WDTIM_MCTRL_RESFRC1 BIT(5)
> +#define WDTIM_MCTRL_M_RES2 BIT(4)
> +#define WDTIM_MCTRL_M_RES1 BIT(3)
> +#define WDTIM_MCTRL_STOP_COUNT0 BIT(2)
> +#define WDTIM_MCTRL_RESET_COUNT0 BIT(1)
> +#define WDTIM_MCTRL_MR0_INT BIT(0)
> +
> +#endif /* _LPC32XX_WDT_H */
Amicalement,
--
Albert.
More information about the U-Boot
mailing list