ARM: add basic support for the Broadcom BCM2835 SoC
This SoC is used in the Raspberry Pi, for example. For more details, see: http://www.broadcom.com/products/BCM2835 http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf. Initial support is enough to boot to a serial console, execute a minimal set of U-Boot commands, download data over a serial port, and boot a Linux kernel. No storage or network drivers are implemented. GPIO driver originally by Vikram Narayanan <vikram186@gmail.com> with many fixes from myself. Signed-off-by: Stephen Warren <swarren@wwwdotorg.org>
This commit is contained in:
parent
86c632651d
commit
efad6cf881
37
arch/arm/cpu/arm1176/bcm2835/Makefile
Normal file
37
arch/arm/cpu/arm1176/bcm2835/Makefile
Normal file
@ -0,0 +1,37 @@
|
||||
#
|
||||
# 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
|
||||
# version 2 as published by the Free Software Foundation.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(SOC).o
|
||||
|
||||
SOBJS := lowlevel_init.o
|
||||
COBJS := reset.o timer.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.c) $(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
|
||||
|
||||
#########################################################################
|
19
arch/arm/cpu/arm1176/bcm2835/config.mk
Normal file
19
arch/arm/cpu/arm1176/bcm2835/config.mk
Normal file
@ -0,0 +1,19 @@
|
||||
#
|
||||
# (C) Copyright 2012 Stephen Warren
|
||||
#
|
||||
# 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
|
||||
# version 2 as published by the Free Software Foundation.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Don't attempt to override the target CPU/ABI options;
|
||||
# the Raspberry Pi toolchain does the right thing by default.
|
||||
PLATFORM_RELFLAGS := $(filter-out -msoft-float,$(PLATFORM_RELFLAGS))
|
||||
PLATFORM_CPPFLAGS := $(filter-out -march=armv5t,$(PLATFORM_CPPFLAGS))
|
19
arch/arm/cpu/arm1176/bcm2835/lowlevel_init.S
Normal file
19
arch/arm/cpu/arm1176/bcm2835/lowlevel_init.S
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* (C) Copyright 2012 Stephen Warren
|
||||
*
|
||||
* 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.globl lowlevel_init
|
||||
lowlevel_init:
|
||||
mov pc, lr
|
35
arch/arm/cpu/arm1176/bcm2835/reset.c
Normal file
35
arch/arm/cpu/arm1176/bcm2835/reset.c
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* (C) Copyright 2012 Stephen Warren
|
||||
*
|
||||
* 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/wdog.h>
|
||||
|
||||
#define RESET_TIMEOUT 10
|
||||
|
||||
void reset_cpu(ulong addr)
|
||||
{
|
||||
struct bcm2835_wdog_regs *regs =
|
||||
(struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR;
|
||||
uint32_t rstc;
|
||||
|
||||
rstc = readl(®s->rstc);
|
||||
rstc &= ~BCM2835_WDOG_RSTC_WRCFG_MASK;
|
||||
rstc |= BCM2835_WDOG_RSTC_WRCFG_FULL_RESET;
|
||||
|
||||
writel(BCM2835_WDOG_PASSWORD | RESET_TIMEOUT, ®s->wdog);
|
||||
writel(BCM2835_WDOG_PASSWORD | rstc, ®s->rstc);
|
||||
}
|
55
arch/arm/cpu/arm1176/bcm2835/timer.c
Normal file
55
arch/arm/cpu/arm1176/bcm2835/timer.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* (C) Copyright 2012 Stephen Warren
|
||||
*
|
||||
* 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/timer.h>
|
||||
|
||||
int timer_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
struct bcm2835_timer_regs *regs =
|
||||
(struct bcm2835_timer_regs *)BCM2835_TIMER_PHYSADDR;
|
||||
|
||||
return readl(®s->clo) - base;
|
||||
}
|
||||
|
||||
unsigned long long get_ticks(void)
|
||||
{
|
||||
return get_timer(0);
|
||||
}
|
||||
|
||||
ulong get_tbclk(void)
|
||||
{
|
||||
return CONFIG_SYS_HZ;
|
||||
}
|
||||
|
||||
void __udelay(unsigned long usec)
|
||||
{
|
||||
ulong endtime;
|
||||
signed long diff;
|
||||
|
||||
endtime = get_timer(0) + usec;
|
||||
|
||||
do {
|
||||
ulong now = get_timer(0);
|
||||
diff = endtime - now;
|
||||
} while (diff >= 0);
|
||||
}
|
66
arch/arm/include/asm/arch-bcm2835/gpio.h
Normal file
66
arch/arm/include/asm/arch-bcm2835/gpio.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Vikram Narayananan
|
||||
* <vikram186@gmail.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.
|
||||
*/
|
||||
|
||||
#ifndef _BCM2835_GPIO_H_
|
||||
#define _BCM2835_GPIO_H_
|
||||
|
||||
#define BCM2835_GPIO_BASE 0x20200000
|
||||
#define BCM2835_GPIO_COUNT 54
|
||||
|
||||
#define BCM2835_GPIO_FSEL_MASK 0x7
|
||||
#define BCM2835_GPIO_INPUT 0x0
|
||||
#define BCM2835_GPIO_OUTPUT 0x1
|
||||
#define BCM2835_GPIO_ALT0 0x4
|
||||
#define BCM2835_GPIO_ALT1 0x5
|
||||
#define BCM2835_GPIO_ALT2 0x6
|
||||
#define BCM2835_GPIO_ALT3 0x7
|
||||
#define BCM2835_GPIO_ALT4 0x3
|
||||
#define BCM2835_GPIO_ALT5 0x2
|
||||
|
||||
#define BCM2835_GPIO_COMMON_BANK(gpio) ((gpio < 32) ? 0 : 1)
|
||||
#define BCM2835_GPIO_COMMON_SHIFT(gpio) (gpio & 0x1f)
|
||||
|
||||
#define BCM2835_GPIO_FSEL_BANK(gpio) (gpio / 10)
|
||||
#define BCM2835_GPIO_FSEL_SHIFT(gpio) ((gpio % 10) * 3)
|
||||
|
||||
struct bcm2835_gpio_regs {
|
||||
u32 gpfsel[6];
|
||||
u32 reserved1;
|
||||
u32 gpset[2];
|
||||
u32 reserved2;
|
||||
u32 gpclr[2];
|
||||
u32 reserved3;
|
||||
u32 gplev[2];
|
||||
u32 reserved4;
|
||||
u32 gpeds[2];
|
||||
u32 reserved5;
|
||||
u32 gpren[2];
|
||||
u32 reserved6;
|
||||
u32 gpfen[2];
|
||||
u32 reserved7;
|
||||
u32 gphen[2];
|
||||
u32 reserved8;
|
||||
u32 gplen[2];
|
||||
u32 reserved9;
|
||||
u32 gparen[2];
|
||||
u32 reserved10;
|
||||
u32 gppud;
|
||||
u32 gppudclk[2];
|
||||
};
|
||||
|
||||
#endif /* _BCM2835_GPIO_H_ */
|
37
arch/arm/include/asm/arch-bcm2835/timer.h
Normal file
37
arch/arm/include/asm/arch-bcm2835/timer.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* (C) Copyright 2012 Stephen Warren
|
||||
*
|
||||
* 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _BCM2835_TIMER_H
|
||||
#define _BCM2835_TIMER_H
|
||||
|
||||
#define BCM2835_TIMER_PHYSADDR 0x20003000
|
||||
|
||||
struct bcm2835_timer_regs {
|
||||
u32 cs;
|
||||
u32 clo;
|
||||
u32 chi;
|
||||
u32 c0;
|
||||
u32 c1;
|
||||
u32 c2;
|
||||
u32 c3;
|
||||
};
|
||||
|
||||
#define BCM2835_TIMER_CS_M3 (1 << 3)
|
||||
#define BCM2835_TIMER_CS_M2 (1 << 2)
|
||||
#define BCM2835_TIMER_CS_M1 (1 << 1)
|
||||
#define BCM2835_TIMER_CS_M0 (1 << 0)
|
||||
|
||||
#endif
|
36
arch/arm/include/asm/arch-bcm2835/wdog.h
Normal file
36
arch/arm/include/asm/arch-bcm2835/wdog.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* (C) Copyright 2012 Stephen Warren
|
||||
*
|
||||
* 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _BCM2835_TIMER_H
|
||||
#define _BCM2835_TIMER_H
|
||||
|
||||
#define BCM2835_WDOG_PHYSADDR 0x20100000
|
||||
|
||||
struct bcm2835_wdog_regs {
|
||||
u32 unknown0[7];
|
||||
u32 rstc;
|
||||
u32 unknown1;
|
||||
u32 wdog;
|
||||
};
|
||||
|
||||
#define BCM2835_WDOG_PASSWORD 0x5a000000
|
||||
|
||||
#define BCM2835_WDOG_RSTC_WRCFG_MASK 0x00000030
|
||||
#define BCM2835_WDOG_RSTC_WRCFG_FULL_RESET 0x00000020
|
||||
|
||||
#define BCM2835_WDOG_WDOG_TIMEOUT_MASK 0x0000ffff
|
||||
|
||||
#endif
|
@ -43,6 +43,7 @@ COBJS-$(CONFIG_MPC83XX_GPIO) += mpc83xx_gpio.o
|
||||
COBJS-$(CONFIG_SH_GPIO_PFC) += sh_pfc.o
|
||||
COBJS-$(CONFIG_OMAP_GPIO) += omap_gpio.o
|
||||
COBJS-$(CONFIG_DB8500_GPIO) += db8500_gpio.o
|
||||
COBJS-$(CONFIG_BCM2835_GPIO) += bcm2835_gpio.o
|
||||
|
||||
COBJS := $(COBJS-y)
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
|
89
drivers/gpio/bcm2835_gpio.c
Normal file
89
drivers/gpio/bcm2835_gpio.c
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Vikram Narayananan
|
||||
* <vikram186@gmail.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.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
inline int gpio_is_valid(unsigned gpio)
|
||||
{
|
||||
return (gpio < BCM2835_GPIO_COUNT);
|
||||
}
|
||||
|
||||
int gpio_request(unsigned gpio, const char *label)
|
||||
{
|
||||
return !gpio_is_valid(gpio);
|
||||
}
|
||||
|
||||
int gpio_free(unsigned gpio)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gpio_direction_input(unsigned gpio)
|
||||
{
|
||||
struct bcm2835_gpio_regs *reg =
|
||||
(struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE;
|
||||
unsigned val;
|
||||
|
||||
val = readl(®->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
|
||||
val &= ~(BCM2835_GPIO_FSEL_MASK << BCM2835_GPIO_FSEL_SHIFT(gpio));
|
||||
val |= (BCM2835_GPIO_INPUT << BCM2835_GPIO_FSEL_SHIFT(gpio));
|
||||
writel(val, ®->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gpio_direction_output(unsigned gpio, int value)
|
||||
{
|
||||
struct bcm2835_gpio_regs *reg =
|
||||
(struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE;
|
||||
unsigned val;
|
||||
|
||||
gpio_set_value(gpio, value);
|
||||
|
||||
val = readl(®->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
|
||||
val &= ~(BCM2835_GPIO_FSEL_MASK << BCM2835_GPIO_FSEL_SHIFT(gpio));
|
||||
val |= (BCM2835_GPIO_OUTPUT << BCM2835_GPIO_FSEL_SHIFT(gpio));
|
||||
writel(val, ®->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gpio_get_value(unsigned gpio)
|
||||
{
|
||||
struct bcm2835_gpio_regs *reg =
|
||||
(struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE;
|
||||
unsigned val;
|
||||
|
||||
val = readl(®->gplev[BCM2835_GPIO_COMMON_BANK(gpio)]);
|
||||
|
||||
return (val >> BCM2835_GPIO_COMMON_SHIFT(gpio)) & 0x1;
|
||||
}
|
||||
|
||||
int gpio_set_value(unsigned gpio, int value)
|
||||
{
|
||||
struct bcm2835_gpio_regs *reg =
|
||||
(struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE;
|
||||
u32 *output_reg = value ? reg->gpset : reg->gpclr;
|
||||
|
||||
writel(1 << BCM2835_GPIO_COMMON_SHIFT(gpio),
|
||||
&output_reg[BCM2835_GPIO_COMMON_BANK(gpio)]);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user