Commit bcc05c7a authored by trem's avatar trem Committed by Stefano Babic

apf27: add support for the armadeus APF27 board

Signed-off-by: default avatarPhilippe Reynes <tremyfr@yahoo.fr>
Signed-off-by: default avatarEric Jarrige <eric.jarrige@armadeus.org>
Signed-off-by: default avatarNicolas Colombain <nicolas.colombain@armadeus.com>
parent a8f2d0e6
......@@ -724,6 +724,11 @@ Ilko Iliev <iliev@ronetix.at>
PM9263 AT91SAM9263
PM9G45 ARM926EJS (AT91SAM9G45 SoC)
Eric Jarrige <eric.jarrige@armadeus.org>
Philippe Reynes <tremyfr@yahoo.fr>
apf27 ARM926EJS (i.MX27 SoC)
Michael Jones <michael.jones@matrix-vision.de>
omap3_mvblx ARM ARMV7 (OMAP3xx SoC)
......
#
# (C) Copyright 2000-2004
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
# (C) Copyright 2012-2013
# Eric Jarrige <eric.jarrige@armadeus.org>
#
# SPDX-License-Identifier: GPL-2.0+
#
include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).o
COBJS := apf27.o
SOBJS := lowlevel_init.o
SRCS := $(COBJS:.o=.c) $(SOBJS:.o=.S)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS))
$(LIB): $(obj).depend $(OBJS) $(SOBJS)
$(call cmd_link_o_target, $(OBJS) $(SOBJS))
#########################################################################
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################
/*
* Copyright (C) 2008-2013 Eric Jarrige <eric.jarrige@armadeus.org>
*
* based on the files by
* Sascha Hauer, Pengutronix
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <environment.h>
#include <jffs2/jffs2.h>
#include <nand.h>
#include <netdev.h>
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/gpio.h>
#include <asm/gpio.h>
#include <asm/errno.h>
#include "apf27.h"
#include "crc.h"
DECLARE_GLOBAL_DATA_PTR;
/*
* Fuse bank 1 row 8 is "reserved for future use" and therefore available for
* customer use. The APF27 board uses this fuse to store the board revision:
* 0: initial board revision
* 1: first revision - Presence of the second RAM chip on the board is blown in
* fuse bank 1 row 9 bit 0 - No hardware change
* N: to be defined
*/
static u32 get_board_rev(void)
{
struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
return readl(&iim->bank[1].fuse_regs[8]);
}
/*
* Fuse bank 1 row 9 is "reserved for future use" and therefore available for
* customer use. The APF27 board revision 1 uses the bit 0 to permanently store
* the presence of the second RAM chip
* 0: AFP27 with 1 RAM of 64 MiB
* 1: AFP27 with 2 RAM chips of 64 MiB each (128MB)
*/
static int get_num_ram_bank(void)
{
struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
int nr_dram_banks = 1;
if ((get_board_rev() > 0) && (CONFIG_NR_DRAM_BANKS > 1))
nr_dram_banks += readl(&iim->bank[1].fuse_regs[9]) & 0x01;
else
nr_dram_banks = CONFIG_NR_DRAM_POPULATED;
return nr_dram_banks;
}
static void apf27_port_init(int port, u32 gpio_dr, u32 ocr1, u32 ocr2,
u32 iconfa1, u32 iconfa2, u32 iconfb1, u32 iconfb2,
u32 icr1, u32 icr2, u32 imr, u32 gpio_dir, u32 gpr,
u32 puen, u32 gius)
{
struct gpio_port_regs *regs = (struct gpio_port_regs *)IMX_GPIO_BASE;
writel(gpio_dr, &regs->port[port].gpio_dr);
writel(ocr1, &regs->port[port].ocr1);
writel(ocr2, &regs->port[port].ocr2);
writel(iconfa1, &regs->port[port].iconfa1);
writel(iconfa2, &regs->port[port].iconfa2);
writel(iconfb1, &regs->port[port].iconfb1);
writel(iconfb2, &regs->port[port].iconfb2);
writel(icr1, &regs->port[port].icr1);
writel(icr2, &regs->port[port].icr2);
writel(imr, &regs->port[port].imr);
writel(gpio_dir, &regs->port[port].gpio_dir);
writel(gpr, &regs->port[port].gpr);
writel(puen, &regs->port[port].puen);
writel(gius, &regs->port[port].gius);
}
#define APF27_PORT_INIT(n) apf27_port_init(PORT##n, ACFG_DR_##n##_VAL, \
ACFG_OCR1_##n##_VAL, ACFG_OCR2_##n##_VAL, ACFG_ICFA1_##n##_VAL, \
ACFG_ICFA2_##n##_VAL, ACFG_ICFB1_##n##_VAL, ACFG_ICFB2_##n##_VAL, \
ACFG_ICR1_##n##_VAL, ACFG_ICR2_##n##_VAL, ACFG_IMR_##n##_VAL, \
ACFG_DDIR_##n##_VAL, ACFG_GPR_##n##_VAL, ACFG_PUEN_##n##_VAL, \
ACFG_GIUS_##n##_VAL)
static void apf27_iomux_init(void)
{
APF27_PORT_INIT(A);
APF27_PORT_INIT(B);
APF27_PORT_INIT(C);
APF27_PORT_INIT(D);
APF27_PORT_INIT(E);
APF27_PORT_INIT(F);
}
static int apf27_devices_init(void)
{
int i;
unsigned int mode[] = {
PC5_PF_I2C2_DATA,
PC6_PF_I2C2_CLK,
PD17_PF_I2C_DATA,
PD18_PF_I2C_CLK,
};
for (i = 0; i < ARRAY_SIZE(mode); i++)
imx_gpio_mode(mode[i]);
#ifdef CONFIG_MXC_UART
mx27_uart1_init_pins();
#endif
#ifdef CONFIG_FEC_MXC
mx27_fec_init_pins();
#endif
#ifdef CONFIG_MXC_MMC
mx27_sd2_init_pins();
imx_gpio_mode((GPIO_PORTF | GPIO_OUT | GPIO_PUEN | GPIO_GPIO | 16));
gpio_request(PC_PWRON, "pc_pwron");
gpio_set_value(PC_PWRON, 1);
#endif
return 0;
}
static void apf27_setup_csx(void)
{
struct weim_regs *weim = (struct weim_regs *)IMX_WEIM_BASE;
writel(ACFG_CS0U_VAL, &weim->cs0u);
writel(ACFG_CS0L_VAL, &weim->cs0l);
writel(ACFG_CS0A_VAL, &weim->cs0a);
writel(ACFG_CS1U_VAL, &weim->cs1u);
writel(ACFG_CS1L_VAL, &weim->cs1l);
writel(ACFG_CS1A_VAL, &weim->cs1a);
writel(ACFG_CS2U_VAL, &weim->cs2u);
writel(ACFG_CS2L_VAL, &weim->cs2l);
writel(ACFG_CS2A_VAL, &weim->cs2a);
writel(ACFG_CS3U_VAL, &weim->cs3u);
writel(ACFG_CS3L_VAL, &weim->cs3l);
writel(ACFG_CS3A_VAL, &weim->cs3a);
writel(ACFG_CS4U_VAL, &weim->cs4u);
writel(ACFG_CS4L_VAL, &weim->cs4l);
writel(ACFG_CS4A_VAL, &weim->cs4a);
writel(ACFG_CS5U_VAL, &weim->cs5u);
writel(ACFG_CS5L_VAL, &weim->cs5l);
writel(ACFG_CS5A_VAL, &weim->cs5a);
writel(ACFG_EIM_VAL, &weim->eim);
}
static void apf27_setup_port(void)
{
struct system_control_regs *system =
(struct system_control_regs *)IMX_SYSTEM_CTL_BASE;
writel(ACFG_FMCR_VAL, &system->fmcr);
}
int board_init(void)
{
gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
apf27_setup_csx();
apf27_setup_port();
apf27_iomux_init();
apf27_devices_init();
return 0;
}
int dram_init(void)
{
gd->ram_size = get_ram_size((void *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
if (get_num_ram_bank() > 1)
gd->ram_size += get_ram_size((void *)PHYS_SDRAM_2,
PHYS_SDRAM_2_SIZE);
return 0;
}
void dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = get_ram_size((void *)PHYS_SDRAM_1,
PHYS_SDRAM_1_SIZE);
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
if (get_num_ram_bank() > 1)
gd->bd->bi_dram[1].size = get_ram_size((void *)PHYS_SDRAM_2,
PHYS_SDRAM_2_SIZE);
else
gd->bd->bi_dram[1].size = 0;
}
ulong board_get_usable_ram_top(ulong total_size)
{
ulong ramtop;
if (get_num_ram_bank() > 1)
ramtop = PHYS_SDRAM_2 + get_ram_size((void *)PHYS_SDRAM_2,
PHYS_SDRAM_2_SIZE);
else
ramtop = PHYS_SDRAM_1 + get_ram_size((void *)PHYS_SDRAM_1,
PHYS_SDRAM_1_SIZE);
return ramtop;
}
int checkboard(void)
{
printf("Board: Armadeus APF27 revision %d\n", get_board_rev());
return 0;
}
#ifdef CONFIG_SPL_BUILD
inline void hang(void)
{
for (;;)
;
}
void board_init_f(ulong bootflag)
{
/*
* copy ourselves from where we are running to where we were
* linked at. Use ulong pointers as all addresses involved
* are 4-byte-aligned.
*/
ulong *start_ptr, *end_ptr, *link_ptr, *run_ptr, *dst;
asm volatile ("ldr %0, =_start" : "=r"(start_ptr));
asm volatile ("ldr %0, =_end" : "=r"(end_ptr));
asm volatile ("ldr %0, =board_init_f" : "=r"(link_ptr));
asm volatile ("adr %0, board_init_f" : "=r"(run_ptr));
for (dst = start_ptr; dst < end_ptr; dst++)
*dst = *(dst+(run_ptr-link_ptr));
/*
* branch to nand_boot's link-time address.
*/
asm volatile("ldr pc, =nand_boot");
}
#endif /* CONFIG_SPL_BUILD */
This diff is collapsed.
/*
* (C) Copyright 2013 Philippe Reynes <tremyfr@yahoo.fr>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <config.h>
#include <generated/asm-offsets.h>
#include <version.h>
#include <asm/macro.h>
#include <asm/arch/imx-regs.h>
#include "apf27.h"
.macro init_aipi
/*
* setup AIPI1 and AIPI2
*/
write32 AIPI1_PSR0, ACFG_AIPI1_PSR0_VAL
write32 AIPI1_PSR1, ACFG_AIPI1_PSR1_VAL
write32 AIPI2_PSR0, ACFG_AIPI2_PSR0_VAL
write32 AIPI2_PSR1, ACFG_AIPI2_PSR1_VAL
/* Change SDRAM signal strengh */
ldr r0, =GPCR
ldr r1, =ACFG_GPCR_VAL
ldr r5, [r0]
orr r5, r5, r1
str r5, [r0]
.endm /* init_aipi */
.macro init_clock
ldr r0, =CSCR
/* disable MPLL/SPLL first */
ldr r1, [r0]
bic r1, r1, #(CSCR_MPEN|CSCR_SPEN)
str r1, [r0]
/*
* pll clock initialization predefined in apf27.h
*/
write32 MPCTL0, ACFG_MPCTL0_VAL
write32 SPCTL0, ACFG_SPCTL0_VAL
write32 CSCR, ACFG_CSCR_VAL|CSCR_MPLL_RESTART|CSCR_SPLL_RESTART
/*
* add some delay here
*/
mov r1, #0x1000
1: subs r1, r1, #0x1
bne 1b
/* peripheral clock divider */
write32 PCDR0, ACFG_PCDR0_VAL
write32 PCDR1, ACFG_PCDR1_VAL
/* Configure PCCR0 and PCCR1 */
write32 PCCR0, ACFG_PCCR0_VAL
write32 PCCR1, ACFG_PCCR1_VAL
.endm /* init_clock */
.macro init_ddr
/* wait for SDRAM/LPDDR ready (SDRAMRDY) */
ldr r0, =IMX_ESD_BASE
ldr r4, =ESDMISC_SDRAM_RDY
2: ldr r1, [r0, #ESDMISC_ROF]
ands r1, r1, r4
bpl 2b
/* LPDDR Soft Reset Mobile/Low Power DDR SDRAM. */
ldr r0, =IMX_ESD_BASE
ldr r4, =ACFG_ESDMISC_VAL
orr r1, r4, #ESDMISC_MDDR_DL_RST
str r1, [r0, #ESDMISC_ROF]
/* Hold for more than 200ns */
ldr r1, =0x10000
1: subs r1, r1, #0x1
bne 1b
str r4, [r0]
ldr r0, =IMX_ESD_BASE
ldr r1, =ACFG_SDRAM_ESDCFG_REGISTER_VAL
str r1, [r0, #ESDCFG0_ROF]
ldr r0, =IMX_ESD_BASE
ldr r1, =ACFG_PRECHARGE_CMD
str r1, [r0, #ESDCTL0_ROF]
/* write8(0xA0001000, any value) */
ldr r1, =PHYS_SDRAM_1+ACFG_SDRAM_PRECHARGE_ALL_VAL
strb r2, [r1]
ldr r1, =ACFG_AUTOREFRESH_CMD
str r1, [r0, #ESDCTL0_ROF]
ldr r4, =PHYS_SDRAM_1 /* CSD0 base address */
ldr r6,=0x7 /* load loop counter */
1: str r5,[r4] /* run auto-refresh cycle to array 0 */
subs r6,r6,#1
bne 1b
ldr r1, =ACFG_SET_MODE_REG_CMD
str r1, [r0, #ESDCTL0_ROF]
/* set standard mode register */
ldr r4, = PHYS_SDRAM_1+ACFG_SDRAM_MODE_REGISTER_VAL
strb r2, [r4]
/* set extended mode register */
ldr r4, =PHYS_SDRAM_1+ACFG_SDRAM_EXT_MODE_REGISTER_VAL
strb r5, [r4]
ldr r1, =ACFG_NORMAL_RW_CMD
str r1, [r0, #ESDCTL0_ROF]
/* 2nd sdram */
ldr r0, =IMX_ESD_BASE
ldr r1, =ACFG_SDRAM_ESDCFG_REGISTER_VAL
str r1, [r0, #ESDCFG1_ROF]
ldr r0, =IMX_ESD_BASE
ldr r1, =ACFG_PRECHARGE_CMD
str r1, [r0, #ESDCTL1_ROF]
/* write8(0xB0001000, any value) */
ldr r1, =PHYS_SDRAM_2+ACFG_SDRAM_PRECHARGE_ALL_VAL
strb r2, [r1]
ldr r1, =ACFG_AUTOREFRESH_CMD
str r1, [r0, #ESDCTL1_ROF]
ldr r4, =PHYS_SDRAM_2 /* CSD1 base address */
ldr r6,=0x7 /* load loop counter */
1: str r5,[r4] /* run auto-refresh cycle to array 0 */
subs r6,r6,#1
bne 1b
ldr r1, =ACFG_SET_MODE_REG_CMD
str r1, [r0, #ESDCTL1_ROF]
/* set standard mode register */
ldr r4, =PHYS_SDRAM_2+ACFG_SDRAM_MODE_REGISTER_VAL
strb r2, [r4]
/* set extended mode register */
ldr r4, =PHYS_SDRAM_2+ACFG_SDRAM_EXT_MODE_REGISTER_VAL
strb r2, [r4]
ldr r1, =ACFG_NORMAL_RW_CMD
str r1, [r0, #ESDCTL1_ROF]
.endm /* init_ddr */
.globl lowlevel_init
lowlevel_init:
init_aipi
init_clock
#ifdef CONFIG_SPL_BUILD
init_ddr
#endif
mov pc, lr
......@@ -196,6 +196,7 @@ jadecpu arm arm926ejs jadecpu syteco
mx25pdk arm arm926ejs mx25pdk freescale mx25 mx25pdk:IMX_CONFIG=board/freescale/mx25pdk/imximage.cfg
tx25 arm arm926ejs tx25 karo mx25
zmx25 arm arm926ejs zmx25 syteco mx25
apf27 arm arm926ejs apf27 armadeus mx27
imx27lite arm arm926ejs imx27lite logicpd mx27
magnesium arm arm926ejs imx27lite logicpd mx27
apx4devkit arm arm926ejs apx4devkit bluegiga mxs apx4devkit
......
This diff is collapsed.
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