[U-Boot] [PATCH 01/10] mx27: basic cpu support

Magnus Lilja lilja.magnus at gmail.com
Wed May 6 22:30:55 CEST 2009


Hi

2009/5/6 Ilya Yanok <yanok at emcraft.com>:
> This patch adds generic code to support Freescale's i.MX27 SoCs.
>
> Signed-off-by: Ilya Yanok <yanok at emcraft.com>
> ---
>  cpu/arm926ejs/mx27/Makefile          |   44 +++
>  cpu/arm926ejs/mx27/generic.c         |  205 ++++++++++++++
>  cpu/arm926ejs/mx27/interrupt.c       |  201 ++++++++++++++
>  include/asm-arm/arch-mx27/clock.h    |   17 ++
>  include/asm-arm/arch-mx27/imx-regs.h |  504 ++++++++++++++++++++++++++++++++++
>  5 files changed, 971 insertions(+), 0 deletions(-)
>  create mode 100644 cpu/arm926ejs/mx27/Makefile
>  create mode 100644 cpu/arm926ejs/mx27/generic.c
>  create mode 100644 cpu/arm926ejs/mx27/interrupt.c
>  create mode 100644 include/asm-arm/arch-mx27/clock.h
>  create mode 100644 include/asm-arm/arch-mx27/imx-regs.h
>
> diff --git a/cpu/arm926ejs/mx27/Makefile b/cpu/arm926ejs/mx27/Makefile
> new file mode 100644
> index 0000000..c86f3c2
> --- /dev/null
> +++ b/cpu/arm926ejs/mx27/Makefile
> @@ -0,0 +1,44 @@
> +#
> +# (C) Copyright 2000-2006
> +# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
> +#
> +# 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).a
> +
> +COBJS  = interrupt.o generic.o
> +
> +SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
> +OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
> +
> +all:   $(obj).depend $(LIB)
> +
> +$(LIB):        $(OBJS)
> +       $(AR) $(ARFLAGS) $@ $(OBJS)
> +
> +#########################################################################
> +
> +# defines $(obj).depend target
> +include $(SRCTREE)/rules.mk
> +
> +sinclude $(obj).depend
> +
> +#########################################################################
> diff --git a/cpu/arm926ejs/mx27/generic.c b/cpu/arm926ejs/mx27/generic.c
> new file mode 100644
> index 0000000..fdbc8b7
> --- /dev/null
> +++ b/cpu/arm926ejs/mx27/generic.c
> @@ -0,0 +1,205 @@
> +/*
> + *  Copyright (c) 2008 Eric Jarrige <eric.jarrige at armadeus.org>
> + *  Copyright (c) 2009 Ilya Yanok <yanok at emcraft.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/imx-regs.h>

An empty line after the last #include statement improves readability, IMO.

> +/*
> + *  get the system pll clock in Hz
> + *
> + *                  mfi + mfn / (mfd +1)
> + *  f = 2 * f_ref * --------------------
> + *                        pd + 1
> + */
> +unsigned int imx_decode_pll(unsigned int pll, unsigned int f_ref)
> +{
> +       unsigned int mfi = (pll >> 10) & 0xf;
> +       unsigned int mfn = pll & 0x3ff;
> +       unsigned int mfd = (pll >> 16) & 0x3ff;
> +       unsigned int pd =  (pll >> 26) & 0xf;
> +
> +       mfi = mfi <= 5 ? 5 : mfi;
> +
> +       return lldiv((2*(u64)f_ref* (mfi*(mfd+1) + mfn)), ((mfd+1)*(pd+1)));

Add space before and after * and +

> +}
> +
> +static ulong clk_in_32k(void)
> +{
> +       return 1024 * CONFIG_MX31_CLK32;
> +}
> +
> +static ulong clk_in_26m(void)
> +{
> +       if (CSCR & CSCR_OSC26M_DIV1P5) {
> +               /* divide by 1.5 */
> +               return 26000000 / 1.5;
> +       } else {
> +               /* divide by 1 */
> +               return 26000000;
> +       }
> +}
> +
> +ulong imx_get_mpllclk(void)
> +{
> +       ulong cscr = CSCR;
> +       ulong fref;
> +
> +       if (cscr & CSCR_MCU_SEL)
> +               fref = clk_in_26m();
> +       else
> +               fref = clk_in_32k();
> +
> +       return imx_decode_pll(MPCTL0, fref);
> +}
> +
> +ulong imx_get_armclk(void)
> +{
> +       ulong cscr = CSCR;
> +       ulong fref = imx_get_mpllclk();
> +       ulong div;
> +
> +       if (!(cscr & CSCR_ARM_SRC_MPLL))
> +               fref = lldiv((fref * 2), 3);
> +
> +       div = ((cscr >> 12) & 0x3) + 1;
> +
> +       return lldiv(fref, div);
> +}
> +
> +ulong imx_get_ahbclk(void)
> +{
> +       ulong cscr = CSCR;
> +       ulong fref = imx_get_mpllclk();
> +       ulong div;
> +
> +       div = ((cscr >> 8) & 0x3) + 1;
> +
> +       return lldiv(fref * 2, 3 * div);
> +

Remove empty line.

> +}
> +
> +ulong imx_get_spllclk(void)
> +{
> +       ulong cscr = CSCR;
> +       ulong fref;
> +
> +       if (cscr & CSCR_SP_SEL)
> +               fref = clk_in_26m();
> +       else
> +               fref = clk_in_32k();
> +
> +       return imx_decode_pll(SPCTL0, fref);
> +}
> +
> +static ulong imx_decode_perclk(ulong div)
> +{
> +        return lldiv((imx_get_mpllclk() * 2), (div * 3));

Use tab instead of space for indent.

> +}
> +
> +ulong imx_get_perclk1(void)
> +{
> +       return imx_decode_perclk((PCDR1 & 0x3f) + 1);
> +}
> +
> +ulong imx_get_perclk2(void)
> +{
> +       return imx_decode_perclk(((PCDR1 >> 8) & 0x3f) + 1);
> +}
> +
> +ulong imx_get_perclk3(void)
> +{
> +       return imx_decode_perclk(((PCDR1 >> 16) & 0x3f) + 1);
> +}
> +
> +ulong imx_get_perclk4(void)
> +{
> +       return imx_decode_perclk(((PCDR1 >> 24) & 0x3f) + 1);
> +}
> +
> +#if defined(CONFIG_DISPLAY_CPUINFO)
> +int print_cpuinfo (void)
> +{
> +       printf("CPU:   Freescale i.MX27 at %llu MHz\n",
> +               lldiv(imx_get_mpllclk(), 1000000));
> +       printf("\n");
> +       return 0;
> +}
> +#endif
> +
> +void imx_gpio_mode(int gpio_mode)
> +{
> +       unsigned int pin = gpio_mode & GPIO_PIN_MASK;
> +       unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
> +       unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT;
> +       unsigned int aout = (gpio_mode & GPIO_AOUT_MASK) >> GPIO_AOUT_SHIFT;
> +       unsigned int bout = (gpio_mode & GPIO_BOUT_MASK) >> GPIO_BOUT_SHIFT;
> +       unsigned int tmp;
> +
> +       /* Pullup enable */
> +       if(gpio_mode & GPIO_PUEN)

Add space after if.

> +               PUEN(port) |= (1 << pin);
> +       else
> +               PUEN(port) &= ~(1 << pin);
> +
> +       /* Data direction */
> +       if(gpio_mode & GPIO_OUT)

Add space after if.

> +               DDIR(port) |= 1 << pin;
> +       else
> +               DDIR(port) &= ~(1 << pin);
> +
> +       /* Primary / alternate function */
> +       if(gpio_mode & GPIO_AF)

Add space after if.

> +               GPR(port) |= (1 << pin);
> +       else
> +               GPR(port) &= ~(1 << pin);
> +
> +       /* use as gpio? */
> +       if(!(gpio_mode & (GPIO_PF | GPIO_AF)))

Add space after if.

> +               GIUS(port) |= (1 << pin);
> +       else
> +               GIUS(port) &= ~(1 << pin);
> +
> +       /* Output / input configuration */
> +       if (pin < 16) {
> +               tmp = OCR1(port);
> +               tmp &= ~(3 << (pin * 2));
> +               tmp |= (ocr << (pin * 2));
> +               OCR1(port) = tmp;
> +
> +               ICONFA1(port) &= ~(3 << (pin * 2));
> +               ICONFA1(port) |= aout << (pin * 2);
> +               ICONFB1(port) &= ~(3 << (pin * 2));
> +               ICONFB1(port) |= bout << (pin * 2);
> +       } else {
> +               pin -= 16;
> +
> +               tmp = OCR2(port);
> +               tmp &= ~(3 << (pin * 2));
> +               tmp |= (ocr << (pin * 2));
> +               OCR2(port) = tmp;
> +
> +               ICONFA2(port) &= ~(3 << (pin * 2));
> +               ICONFA2(port) |= aout << (pin * 2);
> +               ICONFB2(port) &= ~(3 << (pin * 2));
> +               ICONFB2(port) |= bout << (pin * 2);
> +       }
> +

Remove empty line.

> +}
> +
> diff --git a/cpu/arm926ejs/mx27/interrupt.c b/cpu/arm926ejs/mx27/interrupt.c
> new file mode 100644
> index 0000000..6138d91
> --- /dev/null
> +++ b/cpu/arm926ejs/mx27/interrupt.c
<..>
> +unsigned long long get_ticks (void)
> +{
> +       ulong now = GPTCNT; /* current tick value */
> +
> +       if (now >= lastinc)     /* normal mode (non roll) */
> +               /* move stamp forward with absolut diff ticks */
> +               timestamp += (now - lastinc);

Add {} for multiline branches?

> +       else                    /* we have rollover of incrementer */
> +               timestamp += (0xFFFFFFFF - lastinc) + now;
> +       lastinc = now;
> +       return timestamp;
> +}
<..>
> diff --git a/include/asm-arm/arch-mx27/clock.h b/include/asm-arm/arch-mx27/clock.h
> new file mode 100644
> index 0000000..f6615d9
> --- /dev/null
> +++ b/include/asm-arm/arch-mx27/clock.h
> @@ -0,0 +1,17 @@
> +
> +#ifndef __ASM_ARCH_CLOCK_H
> +#define __ASM_ARCH_CLOCK_H
> +unsigned int imx_decode_pll(unsigned int pll, unsigned int f_ref);
> +
> +ulong imx_get_mpllclk(void);
> +ulong imx_get_armclk(void);
> +ulong imx_get_spllclk(void);
> +ulong imx_get_fclk(void);
> +ulong imx_get_hclk(void);
> +ulong imx_get_bclk(void);
> +ulong imx_get_perclk1(void);
> +ulong imx_get_perclk2(void);
> +ulong imx_get_perclk3(void);
> +ulong imx_get_ahbclk(void);
> +
> +#endif /* __ASM_ARCH_CLOCK_H */
> diff --git a/include/asm-arm/arch-mx27/imx-regs.h b/include/asm-arm/arch-mx27/imx-regs.h
> new file mode 100644
> index 0000000..a856f7e
> --- /dev/null
> +++ b/include/asm-arm/arch-mx27/imx-regs.h
> @@ -0,0 +1,504 @@
> +/*
> + *
> + * (c) 2007 Pengutronix, Sascha Hauer <s.hauer at pengutronix.de>
> + *
> + * 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
> + */
> +
> +#ifndef _IMX_REGS_H
> +#define _IMX_REGS_H
> +
> +/* ------------------------------------------------------------------------
> + *  Motorola IMX system registers
> + * ------------------------------------------------------------------------
> + */
> +
> +# ifndef __ASSEMBLY__

Why the space after # here?

> +# define __REG(x)      (*((volatile u32 *)(x)))
> +# define __REG16(x)     (*(volatile u16 *)(x))
> +# define __REG2(x,y)    (*(volatile u32 *)((u32)&__REG(x) + (y)))

Add space after comma.

> +
> +extern void imx_gpio_mode (int gpio_mode);
> +
> +# else

Why the space after # here?

> +#  define __REG(x) (x)
> +#  define __REG16(x) (x)
> +#  define __REG2(x,y) ((x)+(y))

Add space after comma.

> +#endif
> +
> +#define IMX_IO_BASE            0x10000000
> +
> +#define IMX_AIPI1_BASE             (0x00000 + IMX_IO_BASE)
> +#define IMX_WDT_BASE               (0x02000 + IMX_IO_BASE)
> +#define IMX_TIM1_BASE              (0x03000 + IMX_IO_BASE)
> +#define IMX_TIM2_BASE              (0x04000 + IMX_IO_BASE)
> +#define IMX_TIM3_BASE              (0x05000 + IMX_IO_BASE)
> +#define IMX_UART1_BASE             (0x0a000 + IMX_IO_BASE)
> +#define IMX_UART2_BASE             (0x0b000 + IMX_IO_BASE)
> +#define IMX_UART3_BASE             (0x0c000 + IMX_IO_BASE)
> +#define IMX_UART4_BASE             (0x0d000 + IMX_IO_BASE)
> +#define IMX_I2C1_BASE              (0x12000 + IMX_IO_BASE)
> +#define IMX_GPIO_BASE              (0x15000 + IMX_IO_BASE)
> +#define IMX_TIM4_BASE              (0x19000 + IMX_IO_BASE)
> +#define IMX_TIM5_BASE              (0x1a000 + IMX_IO_BASE)
> +#define IMX_UART5_BASE             (0x1b000 + IMX_IO_BASE)
> +#define IMX_UART6_BASE             (0x1c000 + IMX_IO_BASE)
> +#define IMX_I2C2_BASE              (0x1D000 + IMX_IO_BASE)
> +#define IMX_TIM6_BASE              (0x1f000 + IMX_IO_BASE)
> +#define IMX_AIPI2_BASE             (0x20000 + IMX_IO_BASE)
> +#define IMX_PLL_BASE               (0x27000 + IMX_IO_BASE)
> +#define IMX_SYSTEM_CTL_BASE        (0x27800 + IMX_IO_BASE)
> +#define IMX_IIM_BASE               (0x28000 + IMX_IO_BASE)
> +#define IMX_FEC_BASE               (0x2b000 + IMX_IO_BASE)
> +
> +#define IMX_ESD_BASE               (0xD8001000)
> +#define IMX_WEIM_BASE              (0xD8002000)

Use tabs to indent the above values.

> +
> +
<...>
> +#define IIM_BANK_AREA  IMX_IIM_BASE + 0x800

Add () around the definition.


Regards, Magnus


More information about the U-Boot mailing list