Compare commits
49 Commits
i2SOM-6ulx
...
rel_imx_2.
| Author | SHA1 | Date | |
|---|---|---|---|
| 0cff1b3d3c | |||
| 7142651386 | |||
| eea025d171 | |||
| 65243d8e35 | |||
| ae238076c6 | |||
| c78103cfad | |||
| 63ce77b674 | |||
| 530e8cb237 | |||
| f712613010 | |||
| af97caf4ff | |||
| f84be76de7 | |||
| 1e25a1c10c | |||
| 1e96c488d0 | |||
| c2590273ef | |||
| 5df28a62da | |||
| f98076caf9 | |||
| 993bd9f320 | |||
| b68a633562 | |||
| bc1f6fa69a | |||
| 20aa905324 | |||
| 70ec2b9f68 | |||
| f732ca0913 | |||
| 3d891b4cfa | |||
| 35a888b8ef | |||
| fd5482c4c0 | |||
| d4d00b4ceb | |||
| 41876a59ea | |||
| bea1987d05 | |||
| 8c65379798 | |||
| 554b9ee7a6 | |||
| b05d6f097d | |||
| 9cf764d379 | |||
| cb4c05f8d8 | |||
| 192e622a81 | |||
| 5954b33250 | |||
| d73d39d034 | |||
| c878dfb5f2 | |||
| 81fba29f2f | |||
| 103c17735e | |||
| d1cce6ea3e | |||
| 4cd144513e | |||
| 9ffbcea76f | |||
| ad3a535c6a | |||
| 93af7d33b0 | |||
| 38107a4d85 | |||
| 7508ceeeab | |||
| e5b3a2fa60 | |||
| 576faf1cc5 | |||
| 6dff4beda2 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -13,6 +13,7 @@
|
||||
*~
|
||||
*.swp
|
||||
*.patch
|
||||
*.swp
|
||||
|
||||
#
|
||||
# Top-level generic files
|
||||
|
||||
21
Makefile
21
Makefile
@ -2677,6 +2677,9 @@ at91sam9rlek_config : unconfig
|
||||
fi;
|
||||
@$(MKCONFIG) -a at91sam9rlek arm arm926ejs at91sam9rlek atmel at91
|
||||
|
||||
mx25_3stack_config : unconfig
|
||||
@$(MKCONFIG) $(@:_config=) arm arm926ejs mx25_3stack freescale mx25
|
||||
|
||||
########################################################################
|
||||
## ARM Integrator boards - see doc/README-integrator for more info.
|
||||
integratorap_config \
|
||||
@ -2731,6 +2734,9 @@ netstar_config: unconfig
|
||||
omap1510inn_config : unconfig
|
||||
@$(MKCONFIG) $(@:_config=) arm arm925t omap1510inn
|
||||
|
||||
stmp378x_dev_config : unconfig
|
||||
@$(MKCONFIG) $(@:_config=) arm arm926ejs stmp378x_dev NULL stmp378x
|
||||
|
||||
xtract_omap1610xxx = $(subst _cs0boot,,$(subst _cs3boot,,$(subst _cs_autoboot,,$(subst _config,,$1))))
|
||||
|
||||
omap1610inn_config \
|
||||
@ -2964,6 +2970,21 @@ imx31_phycore_config : unconfig
|
||||
mx31ads_config : unconfig
|
||||
@$(MKCONFIG) $(@:_config=) arm arm1136 mx31ads freescale mx31
|
||||
|
||||
mx31_3stack_config : unconfig
|
||||
@$(MKCONFIG) $(@:_config=) arm arm1136 mx31_3stack freescale mx31
|
||||
|
||||
mx35_3stack_config \
|
||||
mx35_3stack_mmc_config: unconfig
|
||||
@$(MKCONFIG) $(@:_config=) arm arm1136 mx35_3stack freescale mx35
|
||||
|
||||
imx51_android_config \
|
||||
imx51_config : unconfig
|
||||
@$(MKCONFIG) $(@:_config=) arm arm_cortexa8 imx51 freescale mx51
|
||||
|
||||
mx51_3stack_android_config \
|
||||
mx51_3stack_config : unconfig
|
||||
@$(MKCONFIG) $(@:_config=) arm arm_cortexa8 mx51_3stack freescale mx51
|
||||
|
||||
omap2420h4_config : unconfig
|
||||
@$(MKCONFIG) $(@:_config=) arm arm1136 omap2420h4 NULL omap24xx
|
||||
|
||||
|
||||
49
board/freescale/imx51/Makefile
Normal file
49
board/freescale/imx51/Makefile
Normal file
@ -0,0 +1,49 @@
|
||||
#
|
||||
# Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
|
||||
#
|
||||
# (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
#
|
||||
# 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$(BOARD).a
|
||||
|
||||
COBJS := imx51.o
|
||||
SOBJS := lowlevel_init.o flash_header.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
SOBJS := $(addprefix $(obj),$(SOBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS) $(SOBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
64
board/freescale/imx51/board-imx51.h
Normal file
64
board/freescale/imx51/board-imx51.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#ifndef __BOARD_FREESCALE_BOARD_IMX51_H__
|
||||
#define __BOARD_FREESCALE_BOARD_IMX51_H__
|
||||
|
||||
/*!
|
||||
* @defgroup BRDCFG_MX51 Board Configuration Options
|
||||
* @ingroup MSL_MX51
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file mx51_3stack/board-imx51.h
|
||||
*
|
||||
* @brief This file contains all the board level configuration options.
|
||||
*
|
||||
* It currently hold the options defined for MX51 3Stack Platform.
|
||||
*
|
||||
* @ingroup BRDCFG_IMX51
|
||||
*/
|
||||
|
||||
/* CPLD offsets */
|
||||
#define PBC_LED_CTRL (0x20000)
|
||||
#define PBC_SB_STAT (0x20008)
|
||||
#define PBC_ID_AAAA (0x20040)
|
||||
#define PBC_ID_5555 (0x20048)
|
||||
#define PBC_VERSION (0x20050)
|
||||
#define PBC_ID_CAFE (0x20058)
|
||||
#define PBC_INT_STAT (0x20010)
|
||||
#define PBC_INT_MASK (0x20038)
|
||||
#define PBC_INT_REST (0x20020)
|
||||
#define PBC_SW_RESET (0x20060)
|
||||
|
||||
/* LED switchs */
|
||||
#define LED_SWITCH_REG 0x00
|
||||
/* buttons */
|
||||
#define SWITCH_BUTTONS_REG 0x08
|
||||
/* status, interrupt */
|
||||
#define INTR_STATUS_REG 0x10
|
||||
#define INTR_MASK_REG 0x38
|
||||
#define INTR_RESET_REG 0x20
|
||||
/* magic word for debug CPLD */
|
||||
#define MAGIC_NUMBER1_REG 0x40
|
||||
#define MAGIC_NUMBER2_REG 0x48
|
||||
/* CPLD code version */
|
||||
#define CPLD_CODE_VER_REG 0x50
|
||||
/* magic word for debug CPLD */
|
||||
#define MAGIC_NUMBER3_REG 0x58
|
||||
/* module reset register*/
|
||||
#define MODULE_RESET_REG 0x60
|
||||
/* CPU ID and Personality ID */
|
||||
#define MCU_BOARD_ID_REG 0x68
|
||||
|
||||
#endif /* __BOARD_FREESCALE_BOARD_IMX51_H__ */
|
||||
1
board/freescale/imx51/config.mk
Normal file
1
board/freescale/imx51/config.mk
Normal file
@ -0,0 +1 @@
|
||||
TEXT_BASE = 0x97800000
|
||||
113
board/freescale/imx51/flash_header.S
Normal file
113
board/freescale/imx51/flash_header.S
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include <asm/arch/mx51.h>
|
||||
#include "board-imx51.h"
|
||||
|
||||
#ifdef CONFIG_FLASH_HEADER
|
||||
#ifndef CONFIG_FLASH_HEADER_OFFSET
|
||||
# error "Must define the offset of flash header"
|
||||
#endif
|
||||
#define MXC_DCD_ITEM(i, type, addr, val) \
|
||||
dcd_node_##i: \
|
||||
.word type ; \
|
||||
.word addr ; \
|
||||
.word val ; \
|
||||
|
||||
.section ".text.flasheader", "x"
|
||||
b _start
|
||||
.org CONFIG_FLASH_HEADER_OFFSET
|
||||
app_code_jump_v: .word _start
|
||||
app_code_code_barker: .word CONFIG_FLASH_HEADER_BARKER
|
||||
app_code_csf: .word 0
|
||||
dcd_ptr_ptr: .word dcd_ptr
|
||||
super_root_key: .word 0
|
||||
dcd_ptr: .word dcd_array_start
|
||||
app_dest_ptr: .word TEXT_BASE
|
||||
dcd_array_start:
|
||||
magic: .word 0xB17219E9
|
||||
dcd_array_size: .word dcd_data_end - dcd_array_start - 8
|
||||
/* DCD */
|
||||
/* DDR2 IOMUX configuration */
|
||||
MXC_DCD_ITEM(1, 4, IOMUXC_BASE_ADDR + 0x8a0, 0x200)
|
||||
MXC_DCD_ITEM(2, 4, IOMUXC_BASE_ADDR + 0x50c, 0x20c5)
|
||||
MXC_DCD_ITEM(3, 4, IOMUXC_BASE_ADDR + 0x510, 0x20c5)
|
||||
MXC_DCD_ITEM(4, 4, IOMUXC_BASE_ADDR + 0x83c, 0x2)
|
||||
MXC_DCD_ITEM(5, 4, IOMUXC_BASE_ADDR + 0x848, 0x2)
|
||||
MXC_DCD_ITEM(6, 4, IOMUXC_BASE_ADDR + 0x4b8, 0xe7)
|
||||
MXC_DCD_ITEM(7, 4, IOMUXC_BASE_ADDR + 0x4bc, 0x45)
|
||||
MXC_DCD_ITEM(8, 4, IOMUXC_BASE_ADDR + 0x4c0, 0x45)
|
||||
MXC_DCD_ITEM(9, 4, IOMUXC_BASE_ADDR + 0x4c4, 0x45)
|
||||
MXC_DCD_ITEM(10, 4, IOMUXC_BASE_ADDR + 0x4c8, 0x45)
|
||||
MXC_DCD_ITEM(11, 4, IOMUXC_BASE_ADDR + 0x820, 0x0)
|
||||
MXC_DCD_ITEM(12, 4, IOMUXC_BASE_ADDR + 0x4a4, 0x3)
|
||||
MXC_DCD_ITEM(13, 4, IOMUXC_BASE_ADDR + 0x4a8, 0x3)
|
||||
MXC_DCD_ITEM(14, 4, IOMUXC_BASE_ADDR + 0x4ac, 0xe3)
|
||||
MXC_DCD_ITEM(15, 4, IOMUXC_BASE_ADDR + 0x4b0, 0xe3)
|
||||
MXC_DCD_ITEM(16, 4, IOMUXC_BASE_ADDR + 0x4b4, 0xe3)
|
||||
MXC_DCD_ITEM(17, 4, IOMUXC_BASE_ADDR + 0x4cc, 0xe3)
|
||||
MXC_DCD_ITEM(18, 4, IOMUXC_BASE_ADDR + 0x4d0, 0xe2)
|
||||
/* Set drive strength to MAX */
|
||||
MXC_DCD_ITEM(19, 4, IOMUXC_BASE_ADDR + 0x82c, 0x6)
|
||||
MXC_DCD_ITEM(20, 4, IOMUXC_BASE_ADDR + 0x8a4, 0x6)
|
||||
MXC_DCD_ITEM(21, 4, IOMUXC_BASE_ADDR + 0x8ac, 0x6)
|
||||
MXC_DCD_ITEM(22, 4, IOMUXC_BASE_ADDR + 0x8b8, 0x6)
|
||||
/* 13 ROW, 10 COL, 32Bit, SREF=4 Micron Model */
|
||||
/* CAS=3, BL=4 */
|
||||
MXC_DCD_ITEM(23, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCTL0, 0x82a20000)
|
||||
MXC_DCD_ITEM(24, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCTL1, 0x82a20000)
|
||||
MXC_DCD_ITEM(25, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDMISC, 0x000ad0d0)
|
||||
MXC_DCD_ITEM(26, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCFG0, 0x333574aa)
|
||||
MXC_DCD_ITEM(27, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCFG1, 0x333574aa)
|
||||
/* Init DRAM on CS0 */
|
||||
MXC_DCD_ITEM(28, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x04008008)
|
||||
MXC_DCD_ITEM(29, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0000801a)
|
||||
MXC_DCD_ITEM(30, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0000801b)
|
||||
MXC_DCD_ITEM(31, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00448019)
|
||||
MXC_DCD_ITEM(32, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x07328018)
|
||||
MXC_DCD_ITEM(33, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x04008008)
|
||||
MXC_DCD_ITEM(34, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008010)
|
||||
MXC_DCD_ITEM(35, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008010)
|
||||
MXC_DCD_ITEM(36, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x06328018)
|
||||
MXC_DCD_ITEM(37, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x03808019)
|
||||
MXC_DCD_ITEM(38, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00408019)
|
||||
MXC_DCD_ITEM(39, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008000)
|
||||
/* Init DRAM on CS1 */
|
||||
MXC_DCD_ITEM(40, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0400800c)
|
||||
MXC_DCD_ITEM(41, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0000801e)
|
||||
MXC_DCD_ITEM(42, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0000801f)
|
||||
MXC_DCD_ITEM(43, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0000801d)
|
||||
MXC_DCD_ITEM(44, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0732801c)
|
||||
MXC_DCD_ITEM(45, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0400800c)
|
||||
MXC_DCD_ITEM(46, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008014)
|
||||
MXC_DCD_ITEM(47, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008014)
|
||||
MXC_DCD_ITEM(48, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0632801c)
|
||||
MXC_DCD_ITEM(49, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0380801d)
|
||||
MXC_DCD_ITEM(50, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0040801d)
|
||||
MXC_DCD_ITEM(51, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008004)
|
||||
MXC_DCD_ITEM(52, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCTL0, 0xb2a20000)
|
||||
MXC_DCD_ITEM(53, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCTL1, 0xb2a20000)
|
||||
MXC_DCD_ITEM(54, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDMISC, 0x000ad6d0)
|
||||
MXC_DCD_ITEM(55, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCDLYGD, 0x90000000)
|
||||
MXC_DCD_ITEM(56, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00000000)
|
||||
dcd_data_end:
|
||||
image_len: .word 0x100000
|
||||
//image_len: .word _end - _start
|
||||
#endif
|
||||
706
board/freescale/imx51/imx51.c
Normal file
706
board/freescale/imx51/imx51.c
Normal file
@ -0,0 +1,706 @@
|
||||
/*
|
||||
* Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
|
||||
*
|
||||
* (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/mx51.h>
|
||||
#include <asm/arch/mx51_pins.h>
|
||||
#include <asm/arch/iomux.h>
|
||||
#include <asm/errno.h>
|
||||
#include <i2c.h>
|
||||
#include <mxc_keyb.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include "board-imx51.h"
|
||||
#include <asm/arch/imx_spi.h>
|
||||
#include <asm/arch/imx_spi_pmic.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static u32 system_rev;
|
||||
u32 mx51_io_base_addr;
|
||||
volatile u32 *esdhc_base_pointer;
|
||||
|
||||
u32 get_board_rev(void)
|
||||
{
|
||||
return system_rev;
|
||||
}
|
||||
|
||||
static inline void setup_soc_rev(void)
|
||||
{
|
||||
int reg;
|
||||
reg = __REG(ROM_SI_REV);
|
||||
switch (reg) {
|
||||
case 0x02:
|
||||
system_rev = 0x51000 | CHIP_REV_1_1;
|
||||
break;
|
||||
case 0x10:
|
||||
if ((__REG(GPIO1_BASE_ADDR + 0x0) & (0x1 << 22)) == 0) {
|
||||
system_rev = 0x51000 | CHIP_REV_2_5;
|
||||
} else {
|
||||
system_rev = 0x51000 | CHIP_REV_2_0;
|
||||
}
|
||||
break;
|
||||
case 0x20:
|
||||
system_rev = 0x51000 | CHIP_REV_3_0;
|
||||
break;
|
||||
default:
|
||||
system_rev = 0x51000 | CHIP_REV_1_0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void set_board_rev(int rev)
|
||||
{
|
||||
system_rev |= (rev & 0xF) << 8;
|
||||
}
|
||||
|
||||
inline int is_soc_rev(int rev)
|
||||
{
|
||||
return (system_rev & 0xFF) - rev;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
|
||||
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setup_uart(void)
|
||||
{
|
||||
unsigned int pad = PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE |
|
||||
PAD_CTL_PUE_PULL | PAD_CTL_DRV_HIGH;
|
||||
mxc_request_iomux(MX51_PIN_UART1_RXD, IOMUX_CONFIG_ALT0);
|
||||
mxc_iomux_set_pad(MX51_PIN_UART1_RXD, pad | PAD_CTL_SRE_FAST);
|
||||
mxc_request_iomux(MX51_PIN_UART1_TXD, IOMUX_CONFIG_ALT0);
|
||||
mxc_iomux_set_pad(MX51_PIN_UART1_TXD, pad | PAD_CTL_SRE_FAST);
|
||||
mxc_request_iomux(MX51_PIN_UART1_RTS, IOMUX_CONFIG_ALT0);
|
||||
mxc_iomux_set_pad(MX51_PIN_UART1_RTS, pad);
|
||||
mxc_request_iomux(MX51_PIN_UART1_CTS, IOMUX_CONFIG_ALT0);
|
||||
mxc_iomux_set_pad(MX51_PIN_UART1_CTS, pad);
|
||||
/* enable GPIO1_9 for CLK0 and GPIO1_8 for CLK02 */
|
||||
writel(0x00000004, 0x73fa83e8);
|
||||
writel(0x00000004, 0x73fa83ec);
|
||||
}
|
||||
|
||||
void setup_nfc(void)
|
||||
{
|
||||
/* Enable NFC IOMUX */
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS0, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS1, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS2, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS3, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS4, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS5, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS6, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS7, IOMUX_CONFIG_ALT0);
|
||||
}
|
||||
|
||||
static void setup_expio(void)
|
||||
{
|
||||
u32 reg;
|
||||
/* CS5 setup */
|
||||
mxc_request_iomux(MX51_PIN_EIM_CS5, IOMUX_CONFIG_ALT0);
|
||||
writel(0x00410089, WEIM_BASE_ADDR + 0x78 + CSGCR1);
|
||||
writel(0x00000002, WEIM_BASE_ADDR + 0x78 + CSGCR2);
|
||||
/* RWSC=50, RADVA=2, RADVN=6, OEA=0, OEN=0, RCSA=0, RCSN=0 */
|
||||
writel(0x32260000, WEIM_BASE_ADDR + 0x78 + CSRCR1);
|
||||
/* APR = 0 */
|
||||
writel(0x00000000, WEIM_BASE_ADDR + 0x78 + CSRCR2);
|
||||
/* WAL=0, WBED=1, WWSC=50, WADVA=2, WADVN=6, WEA=0, WEN=0,
|
||||
* WCSA=0, WCSN=0
|
||||
*/
|
||||
writel(0x72080F00, WEIM_BASE_ADDR + 0x78 + CSWCR1);
|
||||
if ((readw(CS5_BASE_ADDR + PBC_ID_AAAA) == 0xAAAA) &&
|
||||
(readw(CS5_BASE_ADDR + PBC_ID_5555) == 0x5555)) {
|
||||
if (is_soc_rev(CHIP_REV_2_0) < 0) {
|
||||
reg = readl(CCM_BASE_ADDR + CLKCTL_CBCDR);
|
||||
reg = (reg & (~0x70000)) | 0x30000;
|
||||
writel(reg, CCM_BASE_ADDR + CLKCTL_CBCDR);
|
||||
/* make sure divider effective */
|
||||
while (readl(CCM_BASE_ADDR + CLKCTL_CDHIPR) != 0)
|
||||
;
|
||||
writel(0x0, CCM_BASE_ADDR + CLKCTL_CCDR);
|
||||
}
|
||||
mx51_io_base_addr = CS5_BASE_ADDR;
|
||||
} else {
|
||||
/* CS1 */
|
||||
writel(0x00410089, WEIM_BASE_ADDR + 0x18 + CSGCR1);
|
||||
writel(0x00000002, WEIM_BASE_ADDR + 0x18 + CSGCR2);
|
||||
/* RWSC=50, RADVA=2, RADVN=6, OEA=0, OEN=0, RCSA=0, RCSN=0 */
|
||||
writel(0x32260000, WEIM_BASE_ADDR + 0x18 + CSRCR1);
|
||||
/* APR=0 */
|
||||
writel(0x00000000, WEIM_BASE_ADDR + 0x18 + CSRCR2);
|
||||
/* WAL=0, WBED=1, WWSC=50, WADVA=2, WADVN=6, WEA=0,
|
||||
* WEN=0, WCSA=0, WCSN=0
|
||||
*/
|
||||
writel(0x72080F00, WEIM_BASE_ADDR + 0x18 + CSWCR1);
|
||||
mx51_io_base_addr = CS1_BASE_ADDR;
|
||||
}
|
||||
|
||||
/* Reset interrupt status reg */
|
||||
writew(0x1F, mx51_io_base_addr + PBC_INT_REST);
|
||||
writew(0x00, mx51_io_base_addr + PBC_INT_REST);
|
||||
writew(0xFFFF, mx51_io_base_addr + PBC_INT_MASK);
|
||||
|
||||
/* Reset the XUART and Ethernet controllers */
|
||||
reg = readw(mx51_io_base_addr + PBC_SW_RESET);
|
||||
reg |= 0x9;
|
||||
writew(reg, mx51_io_base_addr + PBC_SW_RESET);
|
||||
reg &= ~0x9;
|
||||
writew(reg, mx51_io_base_addr + PBC_SW_RESET);
|
||||
}
|
||||
|
||||
void spi_io_init(struct imx_spi_dev_t *dev)
|
||||
{
|
||||
switch (dev->base) {
|
||||
case CSPI1_BASE_ADDR:
|
||||
/* 000: Select mux mode: ALT0 mux port: MOSI of instance: ecspi1 */
|
||||
mxc_request_iomux(MX51_PIN_CSPI1_MOSI, IOMUX_CONFIG_ALT0);
|
||||
mxc_iomux_set_pad(MX51_PIN_CSPI1_MOSI, 0x105);
|
||||
|
||||
/* 000: Select mux mode: ALT0 mux port: MISO of instance: ecspi1. */
|
||||
mxc_request_iomux(MX51_PIN_CSPI1_MISO, IOMUX_CONFIG_ALT0);
|
||||
mxc_iomux_set_pad(MX51_PIN_CSPI1_MISO, 0x105);
|
||||
|
||||
if (dev->ss == 0) {
|
||||
/* de-select SS1 of instance: ecspi1. */
|
||||
mxc_request_iomux(MX51_PIN_CSPI1_SS1, IOMUX_CONFIG_ALT3);
|
||||
mxc_iomux_set_pad(MX51_PIN_CSPI1_SS1, 0x85);
|
||||
/* 000: Select mux mode: ALT0 mux port: SS0 of instance: ecspi1. */
|
||||
mxc_request_iomux(MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT0);
|
||||
mxc_iomux_set_pad(MX51_PIN_CSPI1_SS0, 0x185);
|
||||
} else if (dev->ss == 1) {
|
||||
/* de-select SS0 of instance: ecspi1. */
|
||||
mxc_request_iomux(MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT3);
|
||||
mxc_iomux_set_pad(MX51_PIN_CSPI1_SS0, 0x85);
|
||||
/* 000: Select mux mode: ALT0 mux port: SS1 of instance: ecspi1. */
|
||||
mxc_request_iomux(MX51_PIN_CSPI1_SS1, IOMUX_CONFIG_ALT0);
|
||||
mxc_iomux_set_pad(MX51_PIN_CSPI1_SS1, 0x105);
|
||||
}
|
||||
|
||||
/* 000: Select mux mode: ALT0 mux port: RDY of instance: ecspi1. */
|
||||
mxc_request_iomux(MX51_PIN_CSPI1_RDY, IOMUX_CONFIG_ALT0);
|
||||
mxc_iomux_set_pad(MX51_PIN_CSPI1_RDY, 0x180);
|
||||
|
||||
/* 000: Select mux mode: ALT0 mux port: SCLK of instance: ecspi1. */
|
||||
mxc_request_iomux(MX51_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT0);
|
||||
mxc_iomux_set_pad(MX51_PIN_CSPI1_SCLK, 0x105);
|
||||
break;
|
||||
case CSPI2_BASE_ADDR:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_fec(void)
|
||||
{
|
||||
/*FEC_MDIO*/
|
||||
writel(0x3, IOMUXC_BASE_ADDR + 0x0D4);
|
||||
writel(0x1FD, IOMUXC_BASE_ADDR + 0x0468);
|
||||
writel(0x0, IOMUXC_BASE_ADDR + 0x0954);
|
||||
|
||||
/*FEC_MDC*/
|
||||
writel(0x2, IOMUXC_BASE_ADDR + 0x13C);
|
||||
writel(0x2004, IOMUXC_BASE_ADDR + 0x0524);
|
||||
|
||||
/* FEC RDATA[3] */
|
||||
writel(0x3, IOMUXC_BASE_ADDR + 0x0EC);
|
||||
writel(0x180, IOMUXC_BASE_ADDR + 0x0480);
|
||||
writel(0x0, IOMUXC_BASE_ADDR + 0x0964);
|
||||
|
||||
/* FEC RDATA[2] */
|
||||
writel(0x3, IOMUXC_BASE_ADDR + 0x0E8);
|
||||
writel(0x180, IOMUXC_BASE_ADDR + 0x047C);
|
||||
writel(0x0, IOMUXC_BASE_ADDR + 0x0960);
|
||||
|
||||
/* FEC RDATA[1] */
|
||||
writel(0x3, IOMUXC_BASE_ADDR + 0x0d8);
|
||||
writel(0x180, IOMUXC_BASE_ADDR + 0x046C);
|
||||
writel(0x0, IOMUXC_BASE_ADDR + 0x095C);
|
||||
|
||||
/* FEC RDATA[0] */
|
||||
writel(0x2, IOMUXC_BASE_ADDR + 0x016C);
|
||||
writel(0x2180, IOMUXC_BASE_ADDR + 0x0554);
|
||||
writel(0x0, IOMUXC_BASE_ADDR + 0x0958);
|
||||
|
||||
/* FEC TDATA[3] */
|
||||
writel(0x2, IOMUXC_BASE_ADDR + 0x148);
|
||||
writel(0x2004, IOMUXC_BASE_ADDR + 0x0530);
|
||||
|
||||
/* FEC TDATA[2] */
|
||||
writel(0x2, IOMUXC_BASE_ADDR + 0x144);
|
||||
writel(0x2004, IOMUXC_BASE_ADDR + 0x052C);
|
||||
|
||||
/* FEC TDATA[1] */
|
||||
writel(0x2, IOMUXC_BASE_ADDR + 0x140);
|
||||
writel(0x2004, IOMUXC_BASE_ADDR + 0x0528);
|
||||
|
||||
/* FEC TDATA[0] */
|
||||
writel(0x2, IOMUXC_BASE_ADDR + 0x0170);
|
||||
writel(0x2004, IOMUXC_BASE_ADDR + 0x0558);
|
||||
|
||||
/* FEC TX_EN */
|
||||
writel(0x1, IOMUXC_BASE_ADDR + 0x014C);
|
||||
writel(0x2004, IOMUXC_BASE_ADDR + 0x0534);
|
||||
|
||||
/* FEC TX_ER */
|
||||
writel(0x2, IOMUXC_BASE_ADDR + 0x0138);
|
||||
writel(0x2004, IOMUXC_BASE_ADDR + 0x0520);
|
||||
|
||||
/* FEC TX_CLK */
|
||||
writel(0x1, IOMUXC_BASE_ADDR + 0x0150);
|
||||
writel(0x2180, IOMUXC_BASE_ADDR + 0x0538);
|
||||
writel(0x0, IOMUXC_BASE_ADDR + 0x0974);
|
||||
|
||||
/* FEC COL */
|
||||
writel(0x1, IOMUXC_BASE_ADDR + 0x0124);
|
||||
writel(0x2180, IOMUXC_BASE_ADDR + 0x0500);
|
||||
writel(0x0, IOMUXC_BASE_ADDR + 0x094c);
|
||||
|
||||
/* FEC RX_CLK */
|
||||
writel(0x1, IOMUXC_BASE_ADDR + 0x0128);
|
||||
writel(0x2180, IOMUXC_BASE_ADDR + 0x0504);
|
||||
writel(0x0, IOMUXC_BASE_ADDR + 0x0968);
|
||||
|
||||
/* FEC CRS */
|
||||
writel(0x3, IOMUXC_BASE_ADDR + 0x0f4);
|
||||
writel(0x180, IOMUXC_BASE_ADDR + 0x0488);
|
||||
writel(0x0, IOMUXC_BASE_ADDR + 0x0950);
|
||||
|
||||
/* FEC RX_ER */
|
||||
writel(0x3, IOMUXC_BASE_ADDR + 0x0f0);
|
||||
writel(0x180, IOMUXC_BASE_ADDR + 0x0484);
|
||||
writel(0x0, IOMUXC_BASE_ADDR + 0x0970);
|
||||
|
||||
/* FEC RX_DV */
|
||||
writel(0x2, IOMUXC_BASE_ADDR + 0x164);
|
||||
writel(0x2180, IOMUXC_BASE_ADDR + 0x054C);
|
||||
writel(0x0, IOMUXC_BASE_ADDR + 0x096C);
|
||||
}
|
||||
|
||||
static void power_init(void)
|
||||
{
|
||||
struct spi_slave *slave;
|
||||
unsigned int val;
|
||||
unsigned int reg;
|
||||
|
||||
#define REV_ATLAS_LITE_1_0 0x8
|
||||
#define REV_ATLAS_LITE_1_1 0x9
|
||||
#define REV_ATLAS_LITE_2_0 0x10
|
||||
#define REV_ATLAS_LITE_2_1 0x11
|
||||
|
||||
slave = spi_pmic_probe();
|
||||
|
||||
/* Write needed to Power Gate 2 register */
|
||||
val = pmic_reg(slave, 34, 0, 0);
|
||||
val &= ~0x10000;
|
||||
pmic_reg(slave, 34, val, 1);
|
||||
|
||||
/* Write needed to update Charger 0 */
|
||||
pmic_reg(slave, 48, 0x0023807F, 1);
|
||||
|
||||
/* power up the system first */
|
||||
pmic_reg(slave, 34, 0x00200000, 1);
|
||||
|
||||
if (is_soc_rev(CHIP_REV_2_0) >= 0) {
|
||||
/* Set core voltage to 1.1V */
|
||||
val = pmic_reg(slave, 24, 0, 0);
|
||||
val = (val & (~0x1F)) | 0x14;
|
||||
pmic_reg(slave, 24, val, 1);
|
||||
|
||||
/* Setup VCC (SW2) to 1.25 */
|
||||
val = pmic_reg(slave, 25, 0, 0);
|
||||
val = (val & (~0x1F)) | 0x1A;
|
||||
pmic_reg(slave, 25, val, 1);
|
||||
|
||||
/* Setup 1V2_DIG1 (SW3) to 1.25 */
|
||||
val = pmic_reg(slave, 26, 0, 0);
|
||||
val = (val & (~0x1F)) | 0x1A;
|
||||
pmic_reg(slave, 26, val, 1);
|
||||
udelay(50);
|
||||
/* Raise the core frequency to 800MHz */
|
||||
writel(0x0, CCM_BASE_ADDR + CLKCTL_CACRR);
|
||||
} else {
|
||||
/* TO 3.0 */
|
||||
/* Setup VCC (SW2) to 1.225 */
|
||||
val = pmic_reg(slave, 25, 0, 0);
|
||||
val = (val & (~0x1F)) | 0x19;
|
||||
pmic_reg(slave, 25, val, 1);
|
||||
|
||||
/* Setup 1V2_DIG1 (SW3) to 1.2 */
|
||||
val = pmic_reg(slave, 26, 0, 0);
|
||||
val = (val & (~0x1F)) | 0x18;
|
||||
pmic_reg(slave, 26, val, 1);
|
||||
}
|
||||
|
||||
if (((pmic_reg(slave, 7, 0, 0) & 0x1F) < REV_ATLAS_LITE_2_0) ||
|
||||
(((pmic_reg(slave, 7, 0, 0) >> 9) & 0x3) == 0)) {
|
||||
/* Set switchers in PWM mode for Atlas 2.0 and lower */
|
||||
/* Setup the switcher mode for SW1 & SW2*/
|
||||
val = pmic_reg(slave, 28, 0, 0);
|
||||
val = (val & (~0x3C0F)) | 0x1405;
|
||||
pmic_reg(slave, 28, val, 1);
|
||||
|
||||
/* Setup the switcher mode for SW3 & SW4 */
|
||||
val = pmic_reg(slave, 29, 0, 0);
|
||||
val = (val & (~0xF0F)) | 0x505;
|
||||
pmic_reg(slave, 29, val, 1);
|
||||
} else {
|
||||
/* Set switchers in Auto in NORMAL mode & STANDBY mode for Atlas 2.0a */
|
||||
/* Setup the switcher mode for SW1 & SW2*/
|
||||
val = pmic_reg(slave, 28, 0, 0);
|
||||
val = (val & (~0x3C0F)) | 0x2008;
|
||||
pmic_reg(slave, 28, val, 1);
|
||||
|
||||
/* Setup the switcher mode for SW3 & SW4 */
|
||||
val = pmic_reg(slave, 29, 0, 0);
|
||||
val = (val & (~0xF0F)) | 0x808;
|
||||
pmic_reg(slave, 29, val, 1);
|
||||
}
|
||||
|
||||
/* Set VDIG to 1.65V, VGEN3 to 1.8V, VCAM to 2.5V */
|
||||
val = pmic_reg(slave, 30, 0, 0);
|
||||
val &= ~0x34030;
|
||||
val |= 0x10020;
|
||||
pmic_reg(slave, 30, val, 1);
|
||||
|
||||
/* Set VVIDEO to 2.775V, VAUDIO to 3V, VSD to 3.15V */
|
||||
val = pmic_reg(slave, 31, 0, 0);
|
||||
val &= ~0x1FC;
|
||||
val |= 0x1F4;
|
||||
pmic_reg(slave, 31, val, 1);
|
||||
|
||||
/* Configure VGEN3 and VCAM regulators to use external PNP */
|
||||
val = 0x208;
|
||||
pmic_reg(slave, 33, val, 1);
|
||||
udelay(200);
|
||||
|
||||
reg = readl(GPIO2_BASE_ADDR + 0x0);
|
||||
reg &= ~0x4000; /* Lower reset line */
|
||||
writel(reg, GPIO2_BASE_ADDR + 0x0);
|
||||
|
||||
reg = readl(GPIO2_BASE_ADDR + 0x4);
|
||||
reg |= 0x4000; /* configure GPIO lines as output */
|
||||
writel(reg, GPIO2_BASE_ADDR + 0x4);
|
||||
|
||||
/* Reset the ethernet controller over GPIO */
|
||||
writel(0x1, IOMUXC_BASE_ADDR + 0x0AC);
|
||||
|
||||
/* Enable VGEN3, VCAM, VAUDIO, VVIDEO, VSD regulators */
|
||||
val = 0x49249;
|
||||
pmic_reg(slave, 33, val, 1);
|
||||
|
||||
udelay(500);
|
||||
|
||||
reg = readl(GPIO2_BASE_ADDR + 0x0);
|
||||
reg |= 0x4000;
|
||||
writel(reg, GPIO2_BASE_ADDR + 0x0);
|
||||
|
||||
spi_pmic_free(slave);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_MULTI
|
||||
|
||||
#if defined(CONFIG_DRIVER_SMC911X)
|
||||
extern int smc911x_initialize(bd_t *bis);
|
||||
#endif
|
||||
int board_eth_init(bd_t *bis)
|
||||
{
|
||||
int rc = -ENODEV;
|
||||
|
||||
#if defined(CONFIG_DRIVER_SMC911X)
|
||||
rc = smc911x_initialize(bis);
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FSL_MMC
|
||||
|
||||
int sdhc_init(void)
|
||||
{
|
||||
u32 interface_esdhc = 0;
|
||||
s32 status = 0;
|
||||
|
||||
interface_esdhc = (readl(SRC_BASE_ADDR + 0x4) & (0x00180000)) >> 19;
|
||||
|
||||
switch (interface_esdhc) {
|
||||
case 0:
|
||||
|
||||
esdhc_base_pointer = (volatile u32 *)MMC_SDHC1_BASE_ADDR;
|
||||
|
||||
mxc_request_iomux(MX51_PIN_SD1_CMD,
|
||||
IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
|
||||
mxc_request_iomux(MX51_PIN_SD1_CLK,
|
||||
IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
|
||||
mxc_request_iomux(MX51_PIN_SD1_DATA0,
|
||||
IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
|
||||
mxc_request_iomux(MX51_PIN_SD1_DATA1,
|
||||
IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
|
||||
mxc_request_iomux(MX51_PIN_SD1_DATA2,
|
||||
IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
|
||||
mxc_request_iomux(MX51_PIN_SD1_DATA3,
|
||||
IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD1_CMD,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
|
||||
PAD_CTL_HYS_ENABLE | PAD_CTL_47K_PU |
|
||||
PAD_CTL_PUE_PULL |
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD1_CLK,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
|
||||
PAD_CTL_HYS_NONE | PAD_CTL_47K_PU |
|
||||
PAD_CTL_PUE_PULL |
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD1_DATA0,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
|
||||
PAD_CTL_HYS_ENABLE | PAD_CTL_47K_PU |
|
||||
PAD_CTL_PUE_PULL |
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD1_DATA1,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
|
||||
PAD_CTL_HYS_ENABLE | PAD_CTL_47K_PU |
|
||||
PAD_CTL_PUE_PULL |
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD1_DATA2,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
|
||||
PAD_CTL_HYS_ENABLE | PAD_CTL_47K_PU |
|
||||
PAD_CTL_PUE_PULL |
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD1_DATA3,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
|
||||
PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PD |
|
||||
PAD_CTL_PUE_PULL |
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
|
||||
break;
|
||||
case 1:
|
||||
esdhc_base_pointer = (volatile u32 *)MMC_SDHC2_BASE_ADDR;
|
||||
|
||||
mxc_request_iomux(MX51_PIN_SD2_CMD,
|
||||
IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
|
||||
mxc_request_iomux(MX51_PIN_SD2_CLK,
|
||||
IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
|
||||
mxc_request_iomux(MX51_PIN_SD2_DATA0,
|
||||
IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_SD2_DATA1,
|
||||
IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_SD2_DATA2,
|
||||
IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_SD2_DATA3,
|
||||
IOMUX_CONFIG_ALT0);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD2_CMD,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_22K_PU |
|
||||
PAD_CTL_SRE_FAST);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD2_CLK,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_22K_PU |
|
||||
PAD_CTL_SRE_FAST);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD2_DATA0,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_22K_PU |
|
||||
PAD_CTL_SRE_FAST);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD2_DATA1,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_22K_PU |
|
||||
PAD_CTL_SRE_FAST);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD2_DATA2,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_22K_PU |
|
||||
PAD_CTL_SRE_FAST);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD2_DATA3,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_22K_PU |
|
||||
PAD_CTL_SRE_FAST);
|
||||
break;
|
||||
case 2:
|
||||
status = 1;
|
||||
break;
|
||||
case 3:
|
||||
status = 1;
|
||||
break;
|
||||
default:
|
||||
status = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return status = 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MXC_KPD)
|
||||
int setup_mxc_kpd()
|
||||
{
|
||||
mxc_request_iomux(MX51_PIN_KEY_COL0, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_COL1, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_COL2, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_COL3, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_COL4, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_COL5, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_ROW0, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_ROW1, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_ROW2, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_ROW3, IOMUX_CONFIG_ALT0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
setup_soc_rev();
|
||||
|
||||
gd->bd->bi_arch_number = MACH_TYPE_MX51_BABBAGE; /* board id for linux */
|
||||
/* address of boot parameters */
|
||||
gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
|
||||
|
||||
setup_uart();
|
||||
setup_nfc();
|
||||
setup_expio();
|
||||
setup_fec();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef BOARD_LATE_INIT
|
||||
int board_late_init(void)
|
||||
{
|
||||
#if defined(CONFIG_FSL_ANDROID) && defined(CONFIG_MXC_KPD)
|
||||
struct kpp_key_info key_info = {0, 0};
|
||||
int switch_delay = CONFIG_ANDROID_BOOTMOD_DELAY;
|
||||
int state = 0, boot_mode_switch = 0;
|
||||
#endif
|
||||
|
||||
power_init();
|
||||
|
||||
#if defined(CONFIG_FSL_ANDROID) && defined(CONFIG_MXC_KPD)
|
||||
mxc_kpp_init();
|
||||
|
||||
puts("Press home + power to enter recovery mode ...\n");
|
||||
|
||||
while ((switch_delay > 0) && (!boot_mode_switch)) {
|
||||
int i;
|
||||
|
||||
--switch_delay;
|
||||
/* delay 100 * 10ms */
|
||||
for (i = 0; !boot_mode_switch && i < 100; ++i) {
|
||||
/* A state machine to scan home + power key */
|
||||
/* Check for home + power */
|
||||
if (mxc_kpp_getc(&key_info)) {
|
||||
switch (state) {
|
||||
case 0:
|
||||
/* First press */
|
||||
if (TEST_HOME_KEY_DEPRESS(key_info.val, key_info.evt)) {
|
||||
/* Press Home */
|
||||
state = 1;
|
||||
} else if (TEST_POWER_KEY_DEPRESS(key_info.val, key_info.evt)) {
|
||||
state = 2;
|
||||
} else {
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* Home is already pressed, try to detect Power */
|
||||
if (TEST_POWER_KEY_DEPRESS(key_info.val,
|
||||
key_info.evt)) {
|
||||
boot_mode_switch = 1;
|
||||
} else {
|
||||
if (TEST_HOME_KEY_DEPRESS(key_info.val,
|
||||
key_info.evt))
|
||||
state = 1;
|
||||
else
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
/* Power is already pressed, try to detect Home */
|
||||
if (TEST_HOME_KEY_DEPRESS(key_info.val,
|
||||
key_info.evt)) {
|
||||
boot_mode_switch = 1;
|
||||
} else {
|
||||
if (TEST_POWER_KEY_DEPRESS(key_info.val,
|
||||
key_info.evt))
|
||||
state = 2;
|
||||
else
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (1 == boot_mode_switch) {
|
||||
printf("Boot mode switched to recovery mode!\n");
|
||||
/* Set env to recovery mode */
|
||||
setenv("bootargs_android", CONFIG_ANDROID_RECOVERY_BOOTARGS);
|
||||
setenv("bootcmd_android", CONFIG_ANDROID_RECOVERY_BOOTCMD);
|
||||
setenv("bootcmd", "run bootcmd_android");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 100; ++i)
|
||||
udelay(10000);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
printf("Board: MX51 BABBAGE ");
|
||||
|
||||
switch (system_rev & 0xff) {
|
||||
case CHIP_REV_3_0:
|
||||
printf("3.0 [");
|
||||
break;
|
||||
case CHIP_REV_2_5:
|
||||
printf("2.5 [");
|
||||
break;
|
||||
case CHIP_REV_2_0:
|
||||
printf("2.0 [");
|
||||
break;
|
||||
case CHIP_REV_1_1:
|
||||
printf("1.1 [");
|
||||
break;
|
||||
case CHIP_REV_1_0:
|
||||
default:
|
||||
printf("1.0 [");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (__REG(SRC_BASE_ADDR + 0x8)) {
|
||||
case 0x0001:
|
||||
printf("POR");
|
||||
break;
|
||||
case 0x0009:
|
||||
printf("RST");
|
||||
break;
|
||||
case 0x0010:
|
||||
case 0x0011:
|
||||
printf("WDOG");
|
||||
break;
|
||||
default:
|
||||
printf("unknown");
|
||||
}
|
||||
printf("]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
319
board/freescale/imx51/lowlevel_init.S
Normal file
319
board/freescale/imx51/lowlevel_init.S
Normal file
@ -0,0 +1,319 @@
|
||||
/*
|
||||
* Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
|
||||
*
|
||||
* (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include <asm/arch/mx51.h>
|
||||
#include "board-imx51.h"
|
||||
|
||||
/*
|
||||
* return soc version
|
||||
* 0x10: TO1
|
||||
* 0x20: TO2
|
||||
* 0x30: TO3
|
||||
*/
|
||||
.macro check_soc_version ret, tmp
|
||||
.endm
|
||||
|
||||
/*
|
||||
* L2CC Cache setup/invalidation/disable
|
||||
*/
|
||||
.macro init_l2cc
|
||||
/* explicitly disable L2 cache */
|
||||
mrc 15, 0, r0, c1, c0, 1
|
||||
bic r0, r0, #0x2
|
||||
mcr 15, 0, r0, c1, c0, 1
|
||||
|
||||
/* reconfigure L2 cache aux control reg */
|
||||
mov r0, #0xC0 /* tag RAM */
|
||||
add r0, r0, #0x4 /* data RAM */
|
||||
orr r0, r0, #(1 << 24) /* disable write allocate delay */
|
||||
orr r0, r0, #(1 << 23) /* disable write allocate combine */
|
||||
orr r0, r0, #(1 << 22) /* disable write allocate */
|
||||
|
||||
cmp r3, #0x10 /* r3 contains the silicon rev */
|
||||
orrls r0, r0, #(1 << 25) /* disable write combine for TO 2 and lower revs */
|
||||
|
||||
mcr 15, 1, r0, c9, c0, 2
|
||||
.endm /* init_l2cc */
|
||||
|
||||
/* AIPS setup - Only setup MPROTx registers.
|
||||
* The PACR default values are good.*/
|
||||
.macro init_aips
|
||||
/*
|
||||
* Set all MPROTx to be non-bufferable, trusted for R/W,
|
||||
* not forced to user-mode.
|
||||
*/
|
||||
ldr r0, =AIPS1_BASE_ADDR
|
||||
ldr r1, =0x77777777
|
||||
str r1, [r0, #0x0]
|
||||
str r1, [r0, #0x4]
|
||||
ldr r0, =AIPS2_BASE_ADDR
|
||||
str r1, [r0, #0x0]
|
||||
str r1, [r0, #0x4]
|
||||
/*
|
||||
* Clear the on and off peripheral modules Supervisor Protect bit
|
||||
* for SDMA to access them. Did not change the AIPS control registers
|
||||
* (offset 0x20) access type
|
||||
*/
|
||||
.endm /* init_aips */
|
||||
|
||||
/* MAX (Multi-Layer AHB Crossbar Switch) setup */
|
||||
.macro init_max
|
||||
.endm /* init_max */
|
||||
|
||||
/* M4IF setup */
|
||||
.macro init_m4if
|
||||
/* VPU and IPU given higher priority (0x4)
|
||||
* IPU accesses with ID=0x1 given highest priority (=0xA)
|
||||
*/
|
||||
ldr r0, =M4IF_BASE_ADDR
|
||||
|
||||
ldr r1, =0x00000203
|
||||
str r1, [r0, #0x40]
|
||||
|
||||
ldr r1, =0x0
|
||||
str r1, [r0, #0x44]
|
||||
|
||||
ldr r1, =0x00120125
|
||||
str r1, [r0, #0x9C]
|
||||
|
||||
ldr r1, =0x001901A3
|
||||
str r1, [r0, #0x48]
|
||||
|
||||
/*
|
||||
ldr r1, =0x00000a01
|
||||
str r1, [r0, #0x48]
|
||||
ldr r1, =0x00000404
|
||||
str r1, [r0, #0x40]
|
||||
*/
|
||||
.endm /* init_m4if */
|
||||
|
||||
/* To support 133MHz DDR */
|
||||
.macro init_drive_strength
|
||||
.endm /* init_drive_strength */
|
||||
|
||||
/* CPLD on CS5 setup */
|
||||
.macro init_debug_board
|
||||
.endm /* init_debug_board */
|
||||
|
||||
.macro setup_pll pll, freq
|
||||
ldr r2, =\pll
|
||||
ldr r1, =0x00001232
|
||||
str r1, [r2, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */
|
||||
mov r1, #0x2
|
||||
str r1, [r2, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */
|
||||
|
||||
str r3, [r2, #PLL_DP_OP]
|
||||
str r3, [r2, #PLL_DP_HFS_OP]
|
||||
|
||||
str r4, [r2, #PLL_DP_MFD]
|
||||
str r4, [r2, #PLL_DP_HFS_MFD]
|
||||
|
||||
str r5, [r2, #PLL_DP_MFN]
|
||||
str r5, [r2, #PLL_DP_HFS_MFN]
|
||||
|
||||
ldr r1, =0x00001232
|
||||
str r1, [r2, #PLL_DP_CTL]
|
||||
1: ldr r1, [r2, #PLL_DP_CTL]
|
||||
ands r1, r1, #0x1
|
||||
beq 1b
|
||||
.endm
|
||||
|
||||
.macro init_clock
|
||||
ldr r0, =CCM_BASE_ADDR
|
||||
|
||||
/* Gate of clocks to the peripherals first */
|
||||
ldr r1, =0x3FFFFFFF
|
||||
str r1, [r0, #CLKCTL_CCGR0]
|
||||
ldr r1, =0x0
|
||||
str r1, [r0, #CLKCTL_CCGR1]
|
||||
str r1, [r0, #CLKCTL_CCGR2]
|
||||
str r1, [r0, #CLKCTL_CCGR3]
|
||||
|
||||
ldr r1, =0x00030000
|
||||
str r1, [r0, #CLKCTL_CCGR4]
|
||||
ldr r1, =0x00FFF030
|
||||
str r1, [r0, #CLKCTL_CCGR5]
|
||||
ldr r1, =0x00000300
|
||||
str r1, [r0, #CLKCTL_CCGR6]
|
||||
|
||||
/* Disable IPU and HSC dividers */
|
||||
mov r1, #0x60000
|
||||
str r1, [r0, #CLKCTL_CCDR]
|
||||
|
||||
/* Make sure to switch the DDR away from PLL 1 */
|
||||
ldr r1, =0x19239145
|
||||
str r1, [r0, #CLKCTL_CBCDR]
|
||||
/* make sure divider effective */
|
||||
1: ldr r1, [r0, #CLKCTL_CDHIPR]
|
||||
cmp r1, #0x0
|
||||
bne 1b
|
||||
|
||||
/* Switch ARM to step clock */
|
||||
mov r1, #0x4
|
||||
str r1, [r0, #CLKCTL_CCSR]
|
||||
mov r3, #DP_OP_800
|
||||
mov r4, #DP_MFD_800
|
||||
mov r5, #DP_MFN_800
|
||||
setup_pll PLL1_BASE_ADDR
|
||||
|
||||
mov r3, #DP_OP_665
|
||||
mov r4, #DP_MFD_665
|
||||
mov r5, #DP_MFN_665
|
||||
setup_pll PLL3_BASE_ADDR
|
||||
|
||||
/* Switch peripheral to PLL 3 */
|
||||
ldr r0, =CCM_BASE_ADDR
|
||||
ldr r1, =0x000010C0
|
||||
str r1, [r0, #CLKCTL_CBCMR]
|
||||
ldr r1, =0x13239145
|
||||
str r1, [r0, #CLKCTL_CBCDR]
|
||||
mov r3, #DP_OP_665
|
||||
mov r4, #DP_MFD_665
|
||||
mov r5, #DP_MFN_665
|
||||
setup_pll PLL2_BASE_ADDR
|
||||
|
||||
/* Switch peripheral to PLL2 */
|
||||
ldr r0, =CCM_BASE_ADDR
|
||||
ldr r1, =0x19239145
|
||||
str r1, [r0, #CLKCTL_CBCDR]
|
||||
ldr r1, =0x000020C0
|
||||
str r1, [r0, #CLKCTL_CBCMR]
|
||||
|
||||
mov r3, #DP_OP_216
|
||||
mov r4, #DP_MFD_216
|
||||
mov r5, #DP_MFN_216
|
||||
setup_pll PLL3_BASE_ADDR
|
||||
|
||||
|
||||
/* Set the platform clock dividers */
|
||||
ldr r0, =ARM_BASE_ADDR
|
||||
ldr r1, =0x00000725
|
||||
str r1, [r0, #0x14]
|
||||
|
||||
ldr r0, =CCM_BASE_ADDR
|
||||
/* Run TO 3.0 at Full speed, for other TO's wait till we increase VDDGP */
|
||||
ldr r1, =0x0
|
||||
ldr r3, [r1, #ROM_SI_REV]
|
||||
cmp r3, #0x10
|
||||
movls r1, #0x1
|
||||
movhi r1, #0
|
||||
str r1, [r0, #CLKCTL_CACRR]
|
||||
|
||||
/* Switch ARM back to PLL 1 */
|
||||
mov r1, #0
|
||||
str r1, [r0, #CLKCTL_CCSR]
|
||||
|
||||
/* setup the rest */
|
||||
/* Use lp_apm (24MHz) source for perclk */
|
||||
ldr r1, =0x000020C2
|
||||
str r1, [r0, #CLKCTL_CBCMR]
|
||||
/* ddr clock from PLL 1, all perclk dividers are 1 since using 24MHz */
|
||||
ldr r1, =0x59E35100
|
||||
str r1, [r0, #CLKCTL_CBCDR]
|
||||
|
||||
/* Restore the default values in the Gate registers */
|
||||
ldr r1, =0xFFFFFFFF
|
||||
str r1, [r0, #CLKCTL_CCGR0]
|
||||
str r1, [r0, #CLKCTL_CCGR1]
|
||||
str r1, [r0, #CLKCTL_CCGR2]
|
||||
str r1, [r0, #CLKCTL_CCGR3]
|
||||
str r1, [r0, #CLKCTL_CCGR4]
|
||||
str r1, [r0, #CLKCTL_CCGR5]
|
||||
str r1, [r0, #CLKCTL_CCGR6]
|
||||
|
||||
/* Use PLL 2 for UART's, get 66.5MHz from it */
|
||||
ldr r1, =0xA5A2A020
|
||||
str r1, [r0, #CLKCTL_CSCMR1]
|
||||
ldr r1, =0x00C30321
|
||||
str r1, [r0, #CLKCTL_CSCDR1]
|
||||
|
||||
/* make sure divider effective */
|
||||
1: ldr r1, [r0, #CLKCTL_CDHIPR]
|
||||
cmp r1, #0x0
|
||||
bne 1b
|
||||
|
||||
mov r1, #0x0
|
||||
str r1, [r0, #CLKCTL_CCDR]
|
||||
|
||||
/* for cko - for ARM div by 8 */
|
||||
mov r1, #0x000A0000
|
||||
add r1, r1, #0x00000F0
|
||||
str r1, [r0, #CLKCTL_CCOSR]
|
||||
.endm
|
||||
|
||||
.macro setup_wdog
|
||||
ldr r0, =WDOG1_BASE_ADDR
|
||||
mov r1, #0x30
|
||||
strh r1, [r0]
|
||||
.endm
|
||||
|
||||
.section ".text.init", "x"
|
||||
|
||||
.globl lowlevel_init
|
||||
lowlevel_init:
|
||||
ldr r0, =GPIO1_BASE_ADDR
|
||||
ldr r1, [r0, #0x0]
|
||||
orr r1, r1, #(1 << 23)
|
||||
str r1, [r0, #0x0]
|
||||
ldr r1, [r0, #0x4]
|
||||
orr r1, r1, #(1 << 23)
|
||||
str r1, [r0, #0x4]
|
||||
|
||||
#ifdef ENABLE_IMPRECISE_ABORT
|
||||
mrs r1, spsr /* save old spsr */
|
||||
mrs r0, cpsr /* read out the cpsr */
|
||||
bic r0, r0, #0x100 /* clear the A bit */
|
||||
msr spsr, r0 /* update spsr */
|
||||
add lr, pc, #0x8 /* update lr */
|
||||
movs pc, lr /* update cpsr */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
msr spsr, r1 /* restore old spsr */
|
||||
#endif
|
||||
|
||||
init_l2cc
|
||||
|
||||
init_aips
|
||||
|
||||
init_max
|
||||
|
||||
init_m4if
|
||||
|
||||
init_drive_strength
|
||||
|
||||
init_clock
|
||||
|
||||
init_debug_board
|
||||
|
||||
/* return from mxc_nand_load */
|
||||
/* r12 saved upper lr*/
|
||||
b mxc_nand_load
|
||||
|
||||
/* Board level setting value */
|
||||
DDR_PERCHARGE_CMD: .word 0x04008008
|
||||
DDR_REFRESH_CMD: .word 0x00008010
|
||||
DDR_LMR1_W: .word 0x00338018
|
||||
DDR_LMR_CMD: .word 0xB2220000
|
||||
DDR_TIMING_W: .word 0xB02567A9
|
||||
DDR_MISC_W: .word 0x000A0104
|
||||
73
board/freescale/imx51/u-boot.lds
Normal file
73
board/freescale/imx51/u-boot.lds
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* January 2004 - Changed to support H4 device
|
||||
* Copyright (c) 2004 Texas Instruments
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
|
||||
*
|
||||
* (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
/* WARNING - the following is hand-optimized to fit within */
|
||||
/* the sector layout of our flash chips! XXX FIXME XXX */
|
||||
board/freescale/imx51/flash_header.o (.text.flasheader)
|
||||
cpu/arm_cortexa8/start.o
|
||||
board/freescale/imx51/libimx51.a (.text)
|
||||
lib_arm/libarm.a (.text)
|
||||
net/libnet.a (.text)
|
||||
drivers/mtd/libmtd.a (.text)
|
||||
drivers/mmc/libmmc.a (.text)
|
||||
|
||||
. = DEFINED(env_offset) ? env_offset : .;
|
||||
common/env_embedded.o(.text)
|
||||
|
||||
*(.text)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(.rodata) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : { *(.data) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.got : { *(.got) }
|
||||
|
||||
. = .;
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
.bss : { *(.bss) }
|
||||
_end = .;
|
||||
}
|
||||
53
board/freescale/mx25_3stack/Makefile
Normal file
53
board/freescale/mx25_3stack/Makefile
Normal file
@ -0,0 +1,53 @@
|
||||
#
|
||||
# (c) Copyright 2009 Freescale Semiconductor
|
||||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@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$(BOARD).a
|
||||
|
||||
COBJS := mx25_3stack.o
|
||||
SOBJS := lowlevel_init.o dcdheader.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
SOBJS := $(addprefix $(obj),$(SOBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS) $(SOBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
1
board/freescale/mx25_3stack/config.mk
Normal file
1
board/freescale/mx25_3stack/config.mk
Normal file
@ -0,0 +1 @@
|
||||
TEXT_BASE = 0x83F00000
|
||||
99
board/freescale/mx25_3stack/dcdheader.S
Normal file
99
board/freescale/mx25_3stack/dcdheader.S
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Freescale Semiconductor
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include <version.h>
|
||||
|
||||
.extern reset
|
||||
|
||||
#define DCDGEN(i,type, addr, data) \
|
||||
dcd_##i: ;\
|
||||
.long type ;\
|
||||
.long addr ;\
|
||||
.long data
|
||||
|
||||
.globl _initheader
|
||||
_initheader:
|
||||
b reset
|
||||
.org 0x400
|
||||
app_code_jump_v: .long reset
|
||||
app_code_barker: .long 0xB1
|
||||
app_code_csf: .long 0
|
||||
hwcfg_ptr_ptr: .long hwcfg_ptr
|
||||
super_root_key: .long 0
|
||||
hwcfg_ptr: .long dcd_data
|
||||
app_dest_ptr: .long TEXT_BASE
|
||||
dcd_data: .long 0xB17219E9
|
||||
|
||||
#ifdef MXC_MEMORY_MDDR
|
||||
dcd_len: .long 12*15
|
||||
#else
|
||||
dcd_len: .long 12*24
|
||||
#endif
|
||||
|
||||
/* WEIM config-CS5 init -- CPLD */
|
||||
DCDGEN( 1, 4, 0xB8002050, 0x0000D843) /* CS5_CSCRU */
|
||||
DCDGEN( 2, 4, 0xB8002054, 0x22252521) /* CS5_CSCRL */
|
||||
DCDGEN( 3, 4, 0xB8002058, 0x22220A00) /* CS5_CSCRA */
|
||||
#ifdef MXC_MEMORY_MDDR
|
||||
/* MDDR init */
|
||||
DCDGEN( 4, 4, 0xB8001010, 0x00000004) /* enable mDDR */
|
||||
DCDGEN( 5, 4, 0xB8001000, 0x92100000) /* precharge command */
|
||||
DCDGEN( 6, 1, 0x80000400, 0x12344321) /* precharge all dummy write */
|
||||
DCDGEN( 7, 4, 0xB8001000, 0xA2100000) /* auto-refresh command */
|
||||
DCDGEN( 8, 4, 0x80000000, 0x12344321) /* dummy write for refresh */
|
||||
DCDGEN( 9, 4, 0x80000000, 0x12344321) /* dummy write for refresh */
|
||||
DCDGEN(10, 4, 0xB8001000, 0xB2100000) /* Load Mode Reg command - cas=3 bl=8 */
|
||||
DCDGEN(11, 1, 0x80000033, 0xda) /* dummy write -- address has the mode bits */
|
||||
DCDGEN(12, 1, 0x81000000, 0xff) /* dummy write -- address has the mode bits */
|
||||
DCDGEN(13, 4, 0xB8001000, 0x82216880)
|
||||
DCDGEN(14, 4, 0xB8001004, 0x00295729)
|
||||
#else
|
||||
/* DDR2 init */
|
||||
DCDGEN( 4, 4, 0xB8001004, 0x0076E83A) /* initial value for ESDCFG0 */
|
||||
DCDGEN( 5, 4, 0xB8001010, 0x00000204) /* ESD_MISC */
|
||||
DCDGEN( 6, 4, 0xB8001000, 0x92210000) /* CS0 precharge command */
|
||||
DCDGEN( 7, 4, 0x80000f00, 0x12344321) /* precharge all dummy write */
|
||||
DCDGEN( 8, 4, 0xB8001000, 0xB2210000) /* Load Mode Register command */
|
||||
DCDGEN( 9, 1, 0x82000000, 0xda) /* dummy write Load EMR2 */
|
||||
DCDGEN(10, 1, 0x83000000, 0xda) /* dummy write Load EMR3 */
|
||||
DCDGEN(11, 1, 0x81000400, 0xda) /* dummy write Load EMR1; enable DLL */
|
||||
DCDGEN(12, 1, 0x80000333, 0xda) /* dummy write Load MR; reset DLL */
|
||||
|
||||
DCDGEN(13, 4, 0xB8001000, 0x92210000) /* CS0 precharge command */
|
||||
DCDGEN(14, 1, 0x80000400, 0x12345678) /* precharge all dummy write */
|
||||
|
||||
DCDGEN(15, 4, 0xB8001000, 0xA2210000) /* select manual refresh mode */
|
||||
DCDGEN(16, 4, 0x80000000, 0x87654321) /* manual refresh */
|
||||
DCDGEN(17, 4, 0x80000000, 0x87654321) /* manual refresh twice */
|
||||
|
||||
DCDGEN(18, 4, 0xB8001000, 0xB2210000) /* Load Mode Register command */
|
||||
DCDGEN(19, 1, 0x80000233, 0xda) /* Load MR; CL=3, BL=8, end DLL reset */
|
||||
DCDGEN(20, 1, 0x81000780, 0xda) /* Load EMR1; OCD default */
|
||||
DCDGEN(21, 1, 0x81000400, 0xda) /* Load EMR1; OCD exit */
|
||||
DCDGEN(22, 4, 0xB8001000, 0x82216080) /* normal mode */
|
||||
DCDGEN(23, 4, 0x43FAC454, 0x00001000) /* IOMUXC_SW_PAD_CTL_GRP_DDRTYPE(1-5) */
|
||||
#endif
|
||||
|
||||
DCDGEN(99, 4, 0x53F80008, 0x20034000) /* CLKCTL ARM=400 AHB=133 */
|
||||
card_cfg: .long UBOOT_IMAGE_SIZE
|
||||
72
board/freescale/mx25_3stack/lowlevel_init.S
Normal file
72
board/freescale/mx25_3stack/lowlevel_init.S
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Freescale Semiconductor
|
||||
*
|
||||
* 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 <asm/arch/mx25-regs.h>
|
||||
|
||||
.macro REG reg, val
|
||||
ldr r2, =\reg
|
||||
ldr r3, =\val
|
||||
str r3, [r2]
|
||||
.endm
|
||||
|
||||
.macro REG8 reg, val
|
||||
ldr r2, =\reg
|
||||
ldr r3, =\val
|
||||
strb r3, [r2]
|
||||
.endm
|
||||
|
||||
.globl lowlevel_init
|
||||
lowlevel_init:
|
||||
|
||||
REG 0x53F80008, 0x20034000 // ARM clk = 399, AHB clk = 133
|
||||
|
||||
/* Init Debug Board CS5 */
|
||||
REG 0xB8002050, 0x0000D843
|
||||
REG 0xB8002054, 0x22252521
|
||||
REG 0xB8002058, 0x22220A00
|
||||
|
||||
/* M3IF setup */
|
||||
ldr r0, =0x00000001
|
||||
str r0, [r1] /* M3IF control reg */
|
||||
|
||||
/* default CLKO to 1/32 of the ARM core */
|
||||
ldr r0, =CCM_MCR
|
||||
ldr r1, =CCM_MCR
|
||||
bic r1, r1, #0x00F00000
|
||||
bic r1, r1, #0x7F000000
|
||||
mov r2, #0x5F000000
|
||||
add r2, r2, #0x00200000
|
||||
orr r1, r1, r2
|
||||
str r1, [r0]
|
||||
|
||||
/* enable all the clocks */
|
||||
ldr r2, =0x1FFFFFFF
|
||||
ldr r0, =CCM_CGR0
|
||||
str r2, [r0]
|
||||
ldr r2, =0xFFFFFFFF
|
||||
ldr r0, =CCM_CGR1
|
||||
str r2, [r0]
|
||||
ldr r2, =0x000FDFFF
|
||||
ldr r0, =CCM_CGR2
|
||||
str r2, [r0]
|
||||
mov pc, lr
|
||||
|
||||
272
board/freescale/mx25_3stack/mx25_3stack.c
Normal file
272
board/freescale/mx25_3stack/mx25_3stack.c
Normal file
@ -0,0 +1,272 @@
|
||||
/*
|
||||
* (c) Copyright 2009 Freescale Semiconductor
|
||||
*
|
||||
* (c) 2007 Pengutronix, Sascha Hauer <s.hauer@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
|
||||
*/
|
||||
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/arch/mx25.h>
|
||||
#include <asm/arch/mx25-regs.h>
|
||||
#include <asm/arch/mx25_pins.h>
|
||||
#include <asm/arch/iomux.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static u32 system_rev;
|
||||
volatile u32 *esdhc_base_pointer;
|
||||
|
||||
u32 get_board_rev(void)
|
||||
{
|
||||
return system_rev;
|
||||
}
|
||||
|
||||
static inline void setup_soc_rev(void)
|
||||
{
|
||||
int reg;
|
||||
reg = __REG(IIM_BASE + IIM_SREV);
|
||||
if (!reg) {
|
||||
reg = __REG(ROMPATCH_REV);
|
||||
reg <<= 4;
|
||||
} else
|
||||
reg += CHIP_REV_1_0;
|
||||
system_rev = 0x25000 + (reg & 0xFF);
|
||||
}
|
||||
|
||||
inline int is_soc_rev(int rev)
|
||||
{
|
||||
return (system_rev & 0xFF) - rev;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
|
||||
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FSL_MMC
|
||||
|
||||
int sdhc_init(void)
|
||||
{
|
||||
u32 interface_esdhc = 0, val = 0;
|
||||
|
||||
interface_esdhc = (readl(CCM_RCSR) & (0x00300000)) >> 20;
|
||||
|
||||
switch (interface_esdhc) {
|
||||
case 0:
|
||||
esdhc_base_pointer = (volatile u32 *)MMC_SDHC1_BASE;
|
||||
/* Pins */
|
||||
writel(0x10, IOMUXC_BASE + 0x190); /* SD1_CMD */
|
||||
writel(0x10, IOMUXC_BASE + 0x194); /* SD1_CLK */
|
||||
writel(0x00, IOMUXC_BASE + 0x198); /* SD1_DATA0 */
|
||||
writel(0x00, IOMUXC_BASE + 0x19c); /* SD1_DATA1 */
|
||||
writel(0x00, IOMUXC_BASE + 0x1a0); /* SD1_DATA2 */
|
||||
writel(0x00, IOMUXC_BASE + 0x1a4); /* SD1_DATA3 */
|
||||
writel(0x06, IOMUXC_BASE + 0x094); /* D12 (SD1_DATA4) */
|
||||
writel(0x06, IOMUXC_BASE + 0x090); /* D13 (SD1_DATA5) */
|
||||
writel(0x06, IOMUXC_BASE + 0x08c); /* D14 (SD1_DATA6) */
|
||||
writel(0x06, IOMUXC_BASE + 0x088); /* D15 (SD1_DATA7) */
|
||||
writel(0x05, IOMUXC_BASE + 0x010); /* A14 (SD1_WP) */
|
||||
writel(0x05, IOMUXC_BASE + 0x014); /* A15 (SD1_DET) */
|
||||
|
||||
/* Pads */
|
||||
writel(0xD1, IOMUXC_BASE + 0x388); /* SD1_CMD */
|
||||
writel(0xD1, IOMUXC_BASE + 0x38c); /* SD1_CLK */
|
||||
writel(0xD1, IOMUXC_BASE + 0x390); /* SD1_DATA0 */
|
||||
writel(0xD1, IOMUXC_BASE + 0x394); /* SD1_DATA1 */
|
||||
writel(0xD1, IOMUXC_BASE + 0x398); /* SD1_DATA2 */
|
||||
writel(0xD1, IOMUXC_BASE + 0x39c); /* SD1_DATA3 */
|
||||
writel(0xD1, IOMUXC_BASE + 0x28c); /* D12 (SD1_DATA4) */
|
||||
writel(0xD1, IOMUXC_BASE + 0x288); /* D13 (SD1_DATA5) */
|
||||
writel(0xD1, IOMUXC_BASE + 0x284); /* D14 (SD1_DATA6) */
|
||||
writel(0xD1, IOMUXC_BASE + 0x280); /* D15 (SD1_DATA7) */
|
||||
writel(0xD1, IOMUXC_BASE + 0x230); /* A14 (SD1_WP) */
|
||||
writel(0xD1, IOMUXC_BASE + 0x234); /* A15 (SD1_DET) */
|
||||
|
||||
/*
|
||||
* Set write protect and card detect gpio as inputs
|
||||
* A14 (SD1_WP) and A15 (SD1_DET)
|
||||
*/
|
||||
val = ~(3 << 0) & readl(GPIO1_BASE + GPIO_GDIR);
|
||||
writel(val, GPIO1_BASE + GPIO_GDIR);
|
||||
break;
|
||||
case 1:
|
||||
esdhc_base_pointer = (volatile u32 *)MMC_SDHC2_BASE;
|
||||
/* Pins */
|
||||
writel(0x16, IOMUXC_BASE + 0x0e8); /* LD8 (SD1_CMD) */
|
||||
writel(0x16, IOMUXC_BASE + 0x0ec); /* LD9 (SD1_CLK) */
|
||||
writel(0x06, IOMUXC_BASE + 0x0f0); /* LD10 (SD1_DATA0) */
|
||||
writel(0x06, IOMUXC_BASE + 0x0f4); /* LD11 (SD1_DATA1) */
|
||||
writel(0x06, IOMUXC_BASE + 0x0f8); /* LD12 (SD1_DATA2) */
|
||||
writel(0x06, IOMUXC_BASE + 0x0fc); /* LD13 (SD1_DATA3) */
|
||||
writel(0x02, IOMUXC_BASE + 0x120); /* CSI_D2 (SD1_DATA4) */
|
||||
writel(0x02, IOMUXC_BASE + 0x124); /* CSI_D3 (SD1_DATA5) */
|
||||
writel(0x02, IOMUXC_BASE + 0x128); /* CSI_D4 (SD1_DATA6) */
|
||||
writel(0x02, IOMUXC_BASE + 0x12c); /* CSI_D5 (SD1_DATA7) */
|
||||
|
||||
/* Pads */
|
||||
writel(0xD1, IOMUXC_BASE + 0x2e0); /* LD8 (SD1_CMD) */
|
||||
writel(0xD1, IOMUXC_BASE + 0x2e4); /* LD9 (SD1_CLK) */
|
||||
writel(0xD1, IOMUXC_BASE + 0x2e8); /* LD10 (SD1_DATA0) */
|
||||
writel(0xD1, IOMUXC_BASE + 0x2ec); /* LD11 (SD1_DATA1) */
|
||||
writel(0xD1, IOMUXC_BASE + 0x2f0); /* LD12 (SD1_DATA2) */
|
||||
writel(0xD1, IOMUXC_BASE + 0x2f4); /* LD13 (SD1_DATA3) */
|
||||
writel(0xD1, IOMUXC_BASE + 0x318); /* CSI_D2 (SD1_DATA4) */
|
||||
writel(0xD1, IOMUXC_BASE + 0x31c); /* CSI_D3 (SD1_DATA5) */
|
||||
writel(0xD1, IOMUXC_BASE + 0x320); /* CSI_D4 (SD1_DATA6) */
|
||||
writel(0xD1, IOMUXC_BASE + 0x324); /* CSI_D5 (SD1_DATA7) */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
int pad;
|
||||
u8 reg[4];
|
||||
|
||||
setup_soc_rev();
|
||||
|
||||
/* setup pins for UART1 */
|
||||
/* UART 1 IOMUX Configs */
|
||||
mxc_request_iomux(MX25_PIN_UART1_RXD, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX25_PIN_UART1_TXD, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX25_PIN_UART1_RTS, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX25_PIN_UART1_CTS, MUX_CONFIG_FUNC);
|
||||
mxc_iomux_set_pad(MX25_PIN_UART1_RXD,
|
||||
PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
|
||||
PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
|
||||
mxc_iomux_set_pad(MX25_PIN_UART1_TXD,
|
||||
PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX25_PIN_UART1_RTS,
|
||||
PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
|
||||
PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
|
||||
mxc_iomux_set_pad(MX25_PIN_UART1_CTS,
|
||||
PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
|
||||
|
||||
/* setup pins for FEC */
|
||||
mxc_request_iomux(MX25_PIN_FEC_TX_CLK, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX25_PIN_FEC_RX_DV, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX25_PIN_FEC_RDATA0, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX25_PIN_FEC_TDATA0, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX25_PIN_FEC_TX_EN, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX25_PIN_FEC_MDC, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX25_PIN_FEC_MDIO, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX25_PIN_FEC_RDATA1, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX25_PIN_FEC_TDATA1, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX25_PIN_POWER_FAIL, MUX_CONFIG_FUNC); /* PHY INT */
|
||||
|
||||
#define FEC_PAD_CTL1 (PAD_CTL_HYS_SCHMITZ | PAD_CTL_PUE_PUD | \
|
||||
PAD_CTL_PKE_ENABLE)
|
||||
#define FEC_PAD_CTL2 (PAD_CTL_PUE_PUD)
|
||||
|
||||
mxc_iomux_set_pad(MX25_PIN_FEC_TX_CLK, FEC_PAD_CTL1);
|
||||
mxc_iomux_set_pad(MX25_PIN_FEC_RX_DV, FEC_PAD_CTL1);
|
||||
mxc_iomux_set_pad(MX25_PIN_FEC_RDATA0, FEC_PAD_CTL1);
|
||||
mxc_iomux_set_pad(MX25_PIN_FEC_TDATA0, FEC_PAD_CTL2);
|
||||
mxc_iomux_set_pad(MX25_PIN_FEC_TX_EN, FEC_PAD_CTL2);
|
||||
mxc_iomux_set_pad(MX25_PIN_FEC_MDC, FEC_PAD_CTL2);
|
||||
mxc_iomux_set_pad(MX25_PIN_FEC_MDIO, FEC_PAD_CTL1 | PAD_CTL_22K_PU);
|
||||
mxc_iomux_set_pad(MX25_PIN_FEC_RDATA1, FEC_PAD_CTL1);
|
||||
mxc_iomux_set_pad(MX25_PIN_FEC_TDATA1, FEC_PAD_CTL2);
|
||||
mxc_iomux_set_pad(MX25_PIN_POWER_FAIL, FEC_PAD_CTL1);
|
||||
|
||||
/*
|
||||
* Set up the FEC_RESET_B and FEC_ENABLE GPIO pins.
|
||||
* Assert FEC_RESET_B, then power up the PHY by asserting
|
||||
* FEC_ENABLE, at the same time lifting FEC_RESET_B.
|
||||
*
|
||||
* FEC_RESET_B: gpio2[3] is ALT 5 mode of pin D12
|
||||
* FEC_ENABLE_B: gpio4[8] is ALT 5 mode of pin A17
|
||||
*/
|
||||
mxc_request_iomux(MX25_PIN_A17, MUX_CONFIG_ALT5); /* FEC_EN */
|
||||
mxc_request_iomux(MX25_PIN_D12, MUX_CONFIG_ALT5); /* FEC_RESET_B */
|
||||
|
||||
mxc_iomux_set_pad(MX25_PIN_A17, PAD_CTL_ODE_OpenDrain);
|
||||
mxc_iomux_set_pad(MX25_PIN_D12, 0);
|
||||
|
||||
mxc_set_gpio_direction(MX25_PIN_A17, 0); /* FEC_EN */
|
||||
mxc_set_gpio_direction(MX25_PIN_D12, 0); /* FEC_RESET_B */
|
||||
|
||||
/* drop PHY power */
|
||||
mxc_set_gpio_dataout(MX25_PIN_A17, 0); /* FEC_EN */
|
||||
|
||||
/* assert reset */
|
||||
mxc_set_gpio_dataout(MX25_PIN_D12, 0); /* FEC_RESET_B */
|
||||
udelay(2); /* spec says 1us min */
|
||||
|
||||
/* turn on PHY power and lift reset */
|
||||
mxc_set_gpio_dataout(MX25_PIN_A17, 1); /* FEC_EN */
|
||||
mxc_set_gpio_dataout(MX25_PIN_D12, 1); /* FEC_RESET_B */
|
||||
|
||||
#define I2C_PAD_CTL (PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | \
|
||||
PAD_CTL_PUE_PUD | PAD_CTL_100K_PU | PAD_CTL_ODE_OpenDrain)
|
||||
|
||||
mxc_request_iomux(MX25_PIN_I2C1_CLK, MUX_CONFIG_SION);
|
||||
mxc_request_iomux(MX25_PIN_I2C1_DAT, MUX_CONFIG_SION);
|
||||
mxc_iomux_set_pad(MX25_PIN_I2C1_CLK, 0x1E8);
|
||||
mxc_iomux_set_pad(MX25_PIN_I2C1_DAT, 0x1E8);
|
||||
|
||||
gd->bd->bi_arch_number = MACH_TYPE_MX25_3DS; /* board id for linux */
|
||||
gd->bd->bi_boot_params = 0x80000100; /* address of boot parameters */
|
||||
|
||||
return 0;
|
||||
|
||||
#undef FEC_PAD_CTL1
|
||||
#undef FEC_PAD_CTL2
|
||||
#undef I2C_PAD_CTL
|
||||
}
|
||||
|
||||
#ifdef BOARD_LATE_INIT
|
||||
int board_late_init(void)
|
||||
{
|
||||
u8 reg[4];
|
||||
|
||||
/* Turn PMIC On*/
|
||||
reg[0] = 0x09;
|
||||
i2c_write(0x54, 0x02, 1, reg, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
printf("Board: i.MX25 MAX PDK (3DS)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_eth_init(bd_t *bis)
|
||||
{
|
||||
int rc = -ENODEV;
|
||||
#if defined(CONFIG_DRIVER_SMC911X)
|
||||
rc = smc911x_initialize(bis);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
62
board/freescale/mx25_3stack/u-boot.lds
Normal file
62
board/freescale/mx25_3stack/u-boot.lds
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* (c) Copyright 2009 Freescale Semiconductor
|
||||
*
|
||||
* January 2004 - Changed to support H4 device
|
||||
* Copyright (c) 2004 Texas Instruments
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Gary Jennejohn, DENX Software Engineering, <gj@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
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
board/freescale/mx25_3stack/dcdheader.o (.text)
|
||||
cpu/arm926ejs/start.o (.text)
|
||||
*(.text)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(.rodata) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : { *(.data) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.got : { *(.got) }
|
||||
|
||||
. = .;
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
.bss : { *(.bss) }
|
||||
_end = .;
|
||||
}
|
||||
47
board/freescale/mx31_3stack/Makefile
Normal file
47
board/freescale/mx31_3stack/Makefile
Normal file
@ -0,0 +1,47 @@
|
||||
#
|
||||
# Copyright (C) 2008, Guennadi Liakhovetski <lg@denx.de>
|
||||
#
|
||||
# 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$(BOARD).a
|
||||
|
||||
COBJS := mx31_3stack.o
|
||||
SOBJS := lowlevel_init.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
SOBJS := $(addprefix $(obj),$(SOBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS) $(SOBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
1
board/freescale/mx31_3stack/config.mk
Normal file
1
board/freescale/mx31_3stack/config.mk
Normal file
@ -0,0 +1 @@
|
||||
TEXT_BASE = 0x87f00000
|
||||
248
board/freescale/mx31_3stack/lowlevel_init.S
Normal file
248
board/freescale/mx31_3stack/lowlevel_init.S
Normal file
@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (C) 2008, Guennadi Liakhovetski <lg@denx.de>
|
||||
* Copyright (C) 2008, Freescale Semiconductor
|
||||
* Modifications for MX31 3Stack board
|
||||
*
|
||||
* 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 <asm/arch/mx31-regs.h>
|
||||
|
||||
.macro REG reg, val
|
||||
ldr r2, =\reg
|
||||
ldr r3, =\val
|
||||
str r3, [r2]
|
||||
.endm
|
||||
|
||||
.macro REG8 reg, val
|
||||
ldr r2, =\reg
|
||||
ldr r3, =\val
|
||||
strb r3, [r2]
|
||||
.endm
|
||||
|
||||
.macro DELAY loops
|
||||
ldr r2, =\loops
|
||||
1:
|
||||
subs r2, r2, #1
|
||||
nop
|
||||
bcs 1b
|
||||
.endm
|
||||
|
||||
.macro init_aips
|
||||
/*
|
||||
* Set all MPROTx to be non-bufferable, trusted for R/W,
|
||||
* not forced to user-mode.
|
||||
*/
|
||||
ldr r0, =0x43F00000
|
||||
ldr r1, =0x77777777
|
||||
str r1, [r0, #0x00]
|
||||
str r1, [r0, #0x04]
|
||||
ldr r0, =0x53F00000
|
||||
str r1, [r0, #0x00]
|
||||
str r1, [r0, #0x04]
|
||||
|
||||
/*
|
||||
* Clear the on and off peripheral modules Supervisor Protect bit
|
||||
* for SDMA to access them. Did not change the AIPS control registers
|
||||
* (offset 0x20) access type
|
||||
*/
|
||||
ldr r0, =0x43F00000
|
||||
ldr r1, =0x0
|
||||
str r1, [r0, #0x40]
|
||||
str r1, [r0, #0x44]
|
||||
str r1, [r0, #0x48]
|
||||
str r1, [r0, #0x4C]
|
||||
ldr r1, [r0, #0x50]
|
||||
and r1, r1, #0x00FFFFFF
|
||||
str r1, [r0, #0x50]
|
||||
|
||||
ldr r0, =0x53F00000
|
||||
ldr r1, =0x0
|
||||
str r1, [r0, #0x40]
|
||||
str r1, [r0, #0x44]
|
||||
str r1, [r0, #0x48]
|
||||
str r1, [r0, #0x4C]
|
||||
ldr r1, [r0, #0x50]
|
||||
and r1, r1, #0x00FFFFFF
|
||||
str r1, [r0, #0x50]
|
||||
.endm /* init_aips */
|
||||
|
||||
.macro init_max
|
||||
ldr r0, =0x43F04000
|
||||
/* MPR - priority is M4 > M2 > M3 > M5 > M0 > M1 */
|
||||
ldr r1, =0x00302154
|
||||
str r1, [r0, #0x000] /* for S0 */
|
||||
str r1, [r0, #0x100] /* for S1 */
|
||||
str r1, [r0, #0x200] /* for S2 */
|
||||
str r1, [r0, #0x300] /* for S3 */
|
||||
str r1, [r0, #0x400] /* for S4 */
|
||||
/* SGPCR - always park on last master */
|
||||
ldr r1, =0x10
|
||||
str r1, [r0, #0x010] /* for S0 */
|
||||
str r1, [r0, #0x110] /* for S1 */
|
||||
str r1, [r0, #0x210] /* for S2 */
|
||||
str r1, [r0, #0x310] /* for S3 */
|
||||
str r1, [r0, #0x410] /* for S4 */
|
||||
/* MGPCR - restore default values */
|
||||
ldr r1, =0x0
|
||||
str r1, [r0, #0x800] /* for M0 */
|
||||
str r1, [r0, #0x900] /* for M1 */
|
||||
str r1, [r0, #0xA00] /* for M2 */
|
||||
str r1, [r0, #0xB00] /* for M3 */
|
||||
str r1, [r0, #0xC00] /* for M4 */
|
||||
str r1, [r0, #0xD00] /* for M5 */
|
||||
.endm /* init_max */
|
||||
|
||||
.macro init_m3if
|
||||
/* Configure M3IF registers */
|
||||
ldr r1, =0xB8003000
|
||||
/*
|
||||
* M3IF Control Register (M3IFCTL)
|
||||
* MRRP[0] = L2CC0 not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[1] = L2CC1 not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[2] = MBX not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[3] = MAX1 not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[4] = SDMA not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[5] = MPEG4 not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[6] = IPU1 on priority list (1 << 6) = 0x00000040
|
||||
* MRRP[7] = IPU2 not on priority list (0 << 0) = 0x00000000
|
||||
* ------------
|
||||
* 0x00000040
|
||||
*/
|
||||
ldr r0, =0x00000040
|
||||
str r0, [r1] /* M3IF control reg */
|
||||
.endm /* init_m3if */
|
||||
|
||||
.macro init_drive_strength
|
||||
/*
|
||||
* Disable maximum drive strength SDRAM/DDR lines by clearing DSE1 bits
|
||||
* in SW_PAD_CTL registers
|
||||
*/
|
||||
|
||||
/* SDCLK */
|
||||
ldr r1, =0x43FAC200
|
||||
ldr r0, [r1, #0x6C]
|
||||
bic r0, r0, #(1 << 12)
|
||||
str r0, [r1, #0x6C]
|
||||
|
||||
/* CAS */
|
||||
ldr r0, [r1, #0x70]
|
||||
bic r0, r0, #(1 << 22)
|
||||
str r0, [r1, #0x70]
|
||||
|
||||
/* RAS */
|
||||
ldr r0, [r1, #0x74]
|
||||
bic r0, r0, #(1 << 2)
|
||||
str r0, [r1, #0x74]
|
||||
|
||||
/* CS2 (CSD0) */
|
||||
ldr r0, [r1, #0x7C]
|
||||
bic r0, r0, #(1 << 22)
|
||||
str r0, [r1, #0x7C]
|
||||
|
||||
/* DQM3 */
|
||||
ldr r0, [r1, #0x84]
|
||||
bic r0, r0, #(1 << 22)
|
||||
str r0, [r1, #0x84]
|
||||
|
||||
/* DQM2, DQM1, DQM0, SD31-SD0, A25-A0, MA10 (0x288..0x2DC) */
|
||||
ldr r2, =22 /* (0x2E0 - 0x288) / 4 = 22 */
|
||||
pad_loop:
|
||||
ldr r0, [r1, #0x88]
|
||||
bic r0, r0, #(1 << 22)
|
||||
bic r0, r0, #(1 << 12)
|
||||
bic r0, r0, #(1 << 2)
|
||||
str r0, [r1, #0x88]
|
||||
add r1, r1, #4
|
||||
subs r2, r2, #0x1
|
||||
bne pad_loop
|
||||
.endm /* init_drive_strength */
|
||||
|
||||
.section ".text.init", "x"
|
||||
|
||||
.globl lowlevel_init
|
||||
lowlevel_init:
|
||||
|
||||
ldr r0, =0x40000015 /* start from AIPS 2GB region */
|
||||
mcr p15, 0, r0, c15, c2, 4
|
||||
|
||||
init_aips
|
||||
|
||||
init_max
|
||||
|
||||
init_m3if
|
||||
|
||||
init_drive_strength
|
||||
|
||||
/* Image Processing Unit: */
|
||||
/* Too early to switch display on? */
|
||||
REG IPU_CONF, IPU_CONF_DI_EN
|
||||
/* Clock Control Module: */
|
||||
REG CCM_CCMR, 0x074B0BF5 /* Use CKIH, MCU PLL off */
|
||||
|
||||
DELAY 0x40000
|
||||
|
||||
REG CCM_CCMR, 0x074B0BF5 | CCMR_MPE /* MCU PLL on */
|
||||
/* Switch to MCU PLL */
|
||||
REG CCM_CCMR, (0x074B0BF5 | CCMR_MPE) & ~CCMR_MDS
|
||||
|
||||
/* 532-133-66.5 */
|
||||
ldr r0, =CCM_BASE
|
||||
ldr r1, =0xFF871D58
|
||||
/* PDR0 */
|
||||
str r1, [r0, #0x4]
|
||||
ldr r1, MPCTL_PARAM_532
|
||||
/* MPCTL */
|
||||
str r1, [r0, #0x10]
|
||||
|
||||
/* Set UPLL=240MHz, USB=60MHz */
|
||||
ldr r1, =0x49FCFE7F
|
||||
/* PDR1 */
|
||||
str r1, [r0, #0x8]
|
||||
ldr r1, UPCTL_PARAM_240
|
||||
/* UPCTL */
|
||||
str r1, [r0, #0x14]
|
||||
/* default CLKO to 1/8 of the ARM core */
|
||||
mov r1, #0x000002C0
|
||||
add r1, r1, #0x00000006
|
||||
/* COSR */
|
||||
str r1, [r0, #0x1c]
|
||||
|
||||
/* initial CSD0 MDDR */
|
||||
REG 0xB8001004, 0x0075E73A
|
||||
REG 0xB8001010, 0x00000002 /* reset */
|
||||
REG 0xB8001010, 0x00000004
|
||||
DELAY 0x10000
|
||||
|
||||
REG 0xB8001000, 0x92100000
|
||||
REG 0x80000F00, 0x0
|
||||
REG 0xB8001000, 0xA2100000
|
||||
REG 0x80000000, 0x0
|
||||
REG 0xB8001000, 0xB2100000
|
||||
REG8 0x80000033, 0x0
|
||||
REG8 0x81000000, 0xff
|
||||
REG 0xB8001000, 0x82226080
|
||||
REG 0x80000000, 0x0
|
||||
REG 0xB8001010, 0x0000000c
|
||||
|
||||
mov r13, ip
|
||||
/* copy blocks of total uboot to DDR */
|
||||
b mxc_nand_load
|
||||
|
||||
MPCTL_PARAM_532:
|
||||
.word (((1-1) << 26) + ((52-1) << 16) + (10 << 10) + (12 << 0))
|
||||
UPCTL_PARAM_240:
|
||||
.word (((2-1) << 26) + ((13-1) << 16) + (9 << 10) + (3 << 0))
|
||||
75
board/freescale/mx31_3stack/mx31_3stack.c
Normal file
75
board/freescale/mx31_3stack/mx31_3stack.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2008, Guennadi Liakhovetski <lg@denx.de>
|
||||
* Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Modifications for MX31 3Stack board
|
||||
*
|
||||
* 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 <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/mx31.h>
|
||||
#include <asm/arch/mx31-regs.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
|
||||
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* CS5: Debug board for ethernet */
|
||||
__REG(CSCR_U(5)) = 0x0000D843;
|
||||
__REG(CSCR_L(5)) = 0x22252521;
|
||||
__REG(CSCR_A(5)) = 0x22220A00;
|
||||
|
||||
/* setup pins for UART1 */
|
||||
mx31_gpio_mux(MUX_RXD1__UART1_RXD_MUX);
|
||||
mx31_gpio_mux(MUX_TXD1__UART1_TXD_MUX);
|
||||
mx31_gpio_mux(MUX_RTS1__UART1_RTS_B);
|
||||
mx31_gpio_mux(MUX_CTS1__UART1_CTS_B);
|
||||
|
||||
/* SPI2 */
|
||||
mx31_gpio_mux((MUX_CTL_FUNC << 8) | MUX_CTL_CSPI2_SS2);
|
||||
mx31_gpio_mux((MUX_CTL_FUNC << 8) | MUX_CTL_CSPI2_SCLK);
|
||||
mx31_gpio_mux((MUX_CTL_FUNC << 8) | MUX_CTL_CSPI2_SPI_RDY);
|
||||
mx31_gpio_mux((MUX_CTL_FUNC << 8) | MUX_CTL_CSPI2_MOSI);
|
||||
mx31_gpio_mux((MUX_CTL_FUNC << 8) | MUX_CTL_CSPI2_MISO);
|
||||
mx31_gpio_mux((MUX_CTL_FUNC << 8) | MUX_CTL_CSPI2_SS0);
|
||||
mx31_gpio_mux((MUX_CTL_FUNC << 8) | MUX_CTL_CSPI2_SS1);
|
||||
|
||||
/* start SPI2 clock */
|
||||
__REG(CCM_CGR2) = __REG(CCM_CGR2) | (3 << 4);
|
||||
|
||||
gd->bd->bi_arch_number = MACH_TYPE_MX31_3DS; /* board id for linux */
|
||||
gd->bd->bi_boot_params = 0x80000100; /* adress of boot parameters */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
printf("Board: MX31 3Stack\n");
|
||||
return 0;
|
||||
}
|
||||
72
board/freescale/mx31_3stack/u-boot.lds
Normal file
72
board/freescale/mx31_3stack/u-boot.lds
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Gary Jennejohn, DENX Software Engineering, <gj@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
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(reset)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
/* WARNING - the following is hand-optimized to fit within */
|
||||
/* the sector layout of our flash chips! XXX FIXME XXX */
|
||||
|
||||
* (.text.head) /* arm reset handler */
|
||||
* (.text.init) /* lowlevel initial */
|
||||
* (.text.load) /* nand copy and load */
|
||||
* (.text.setup)
|
||||
board/freescale/mx31_3stack/libmx31_3stack.a (.text)
|
||||
lib_arm/libarm.a (.text)
|
||||
net/libnet.a (.text)
|
||||
drivers/mtd/libmtd.a (.text)
|
||||
|
||||
. = DEFINED(env_offset) ? env_offset : .;
|
||||
common/env_embedded.o(.text)
|
||||
|
||||
*(.text)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(.rodata) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : { *(.data) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.got : { *(.got) }
|
||||
|
||||
. = .;
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
.bss : { *(.bss) }
|
||||
_end = .;
|
||||
}
|
||||
50
board/freescale/mx35_3stack/Makefile
Normal file
50
board/freescale/mx35_3stack/Makefile
Normal file
@ -0,0 +1,50 @@
|
||||
#
|
||||
# Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
|
||||
#
|
||||
# (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
#
|
||||
# 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$(BOARD).a
|
||||
|
||||
COBJS := mx35_3stack.o
|
||||
SOBJS := lowlevel_init.o
|
||||
SOBJS += flash_header.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
SOBJS := $(addprefix $(obj),$(SOBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS) $(SOBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
107
board/freescale/mx35_3stack/board-mx35_3stack.h
Normal file
107
board/freescale/mx35_3stack/board-mx35_3stack.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
*
|
||||
* (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
|
||||
*
|
||||
* (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 __BOARD_MX35_3STACK_H
|
||||
#define __BOARD_MX35_3STACK_H
|
||||
|
||||
#define UNALIGNED_ACCESS_ENABLE
|
||||
#define LOW_INT_LATENCY_ENABLE
|
||||
#define BRANCH_PREDICTION_ENABLE
|
||||
|
||||
#define L2CC_AUX_CTL_CONFIG 0x00030024
|
||||
|
||||
#define AIPS_MPR_CONFIG 0x77777777
|
||||
#define AIPS_OPACR_CONFIG 0x00000000
|
||||
|
||||
/* MPR - priority is M4 > M2 > M3 > M5 > M0 > M1 */
|
||||
#define MAX_MPR_CONFIG 0x00302154
|
||||
/* SGPCR - always park on last master */
|
||||
#define MAX_SGPCR_CONFIG 0x00000010
|
||||
/* MGPCR - restore default values */
|
||||
#define MAX_MGPCR_CONFIG 0x00000000
|
||||
|
||||
/*
|
||||
* M3IF Control Register (M3IFCTL)
|
||||
* MRRP[0] = L2CC0 not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[1] = L2CC1 not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[2] = MBX not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[3] = MAX1 not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[4] = SDMA not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[5] = MPEG4 not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[6] = IPU1 on priority list (1 << 6) = 0x00000040
|
||||
* MRRP[7] = IPU2 not on priority list (0 << 0) = 0x00000000
|
||||
* ------------
|
||||
* 0x00000040
|
||||
*/
|
||||
#define M3IF_CONFIG 0x00000040
|
||||
|
||||
#define DBG_BASE_ADDR WEIM_CTRL_CS5
|
||||
#define DBG_CSCR_U_CONFIG 0x0000D843
|
||||
#define DBG_CSCR_L_CONFIG 0x22252521
|
||||
#define DBG_CSCR_A_CONFIG 0x22220A00
|
||||
|
||||
#define CCM_CCMR_CONFIG 0x003F4208
|
||||
#define CCM_PDR0_CONFIG 0x00821000
|
||||
|
||||
#define PLL_BRM_OFFSET 31
|
||||
#define PLL_PD_OFFSET 26
|
||||
#define PLL_MFD_OFFSET 16
|
||||
#define PLL_MFI_OFFSET 10
|
||||
|
||||
#define _PLL_BRM(x) ((x) << PLL_BRM_OFFSET)
|
||||
#define _PLL_PD(x) (((x) - 1) << PLL_PD_OFFSET)
|
||||
#define _PLL_MFD(x) (((x) - 1) << PLL_MFD_OFFSET)
|
||||
#define _PLL_MFI(x) ((x) << PLL_MFI_OFFSET)
|
||||
#define _PLL_MFN(x) (x)
|
||||
#define _PLL_SETTING(brm, pd, mfd, mfi, mfn) \
|
||||
(_PLL_BRM(brm) | _PLL_PD(pd) | _PLL_MFD(mfd) | _PLL_MFI(mfi) |\
|
||||
_PLL_MFN(mfn))
|
||||
|
||||
#define CCM_MPLL_532_HZ _PLL_SETTING(1, 1, 12, 11, 1)
|
||||
#define CCM_MPLL_399_HZ _PLL_SETTING(0, 1, 16, 8, 5)
|
||||
#define CCM_PPLL_300_HZ _PLL_SETTING(0, 1, 4, 6, 1)
|
||||
|
||||
/*MEMORY SETING*/
|
||||
#define ESDCTL_0x92220000 0x92220000
|
||||
#define ESDCTL_0xA2220000 0xA2220000
|
||||
#define ESDCTL_0xB2220000 0xB2220000
|
||||
#define ESDCTL_0x82228080 0x82228080
|
||||
|
||||
#define ESDCTL_PRECHARGE 0x00000400
|
||||
|
||||
#define ESDCTL_MDDR_CONFIG 0x007FFC3F
|
||||
#define ESDCTL_MDDR_MR 0x00000033
|
||||
#define ESDCTL_MDDR_EMR 0x02000000
|
||||
|
||||
#define ESDCTL_DDR2_CONFIG 0x007FFC3F
|
||||
#define ESDCTL_DDR2_EMR2 0x04000000
|
||||
#define ESDCTL_DDR2_EMR3 0x06000000
|
||||
#define ESDCTL_DDR2_EN_DLL 0x02000400
|
||||
#define ESDCTL_DDR2_RESET_DLL 0x00000333
|
||||
#define ESDCTL_DDR2_MR 0x00000233
|
||||
#define ESDCTL_DDR2_OCD_DEFAULT 0x02000780
|
||||
|
||||
#define ESDCTL_DELAY_LINE5 0x00F49F00
|
||||
#endif /* __BOARD_MX35_3STACK_H */
|
||||
1
board/freescale/mx35_3stack/config.mk
Normal file
1
board/freescale/mx35_3stack/config.mk
Normal file
@ -0,0 +1 @@
|
||||
TEXT_BASE = 0x87800000
|
||||
108
board/freescale/mx35_3stack/flash_header.S
Normal file
108
board/freescale/mx35_3stack/flash_header.S
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include <asm/arch/mx35.h>
|
||||
#include "board-mx35_3stack.h"
|
||||
|
||||
#ifdef CONFIG_FLASH_HEADER
|
||||
#ifndef CONFIG_FLASH_HEADER_OFFSET
|
||||
# error "Must define the offset of flash header"
|
||||
#endif
|
||||
|
||||
/* Flash header setup */
|
||||
#define DCDGEN(i,type, addr, data) \
|
||||
dcd_##i: ;\
|
||||
.long type ;\
|
||||
.long addr ;\
|
||||
.long data
|
||||
|
||||
#define GEN_FHEADERADDR(x) (x)
|
||||
|
||||
.section ".text.flasheader", "x"
|
||||
b _start
|
||||
.org CONFIG_FLASH_HEADER_OFFSET
|
||||
app_code_jump_v: .long GEN_FHEADERADDR(_start)
|
||||
app_code_barker: .long CONFIG_FLASH_HEADER_BARKER
|
||||
app_code_csf: .long 0
|
||||
hwcfg_ptr_ptr: .long GEN_FHEADERADDR(hwcfg_ptr)
|
||||
super_root_key: .long 0
|
||||
hwcfg_ptr: .long GEN_FHEADERADDR(dcd_data)
|
||||
app_dest_ptr: .long TEXT_BASE
|
||||
dcd_data: .long 0xB17219E9
|
||||
#ifdef MEMORY_MDDR_ENABLE
|
||||
.long (dcd_data_end - dcd_data - 8)
|
||||
|
||||
//WEIM config-CS5 init
|
||||
DCDGEN(1, 4, 0xB8002054, 0x444a4541)
|
||||
DCDGEN(1_1, 4, 0xB8002050, 0x0000dcf6)
|
||||
DCDGEN(1_2, 4, 0xB8002058, 0x44443302)
|
||||
//MDDR init
|
||||
//enable mDDR
|
||||
DCDGEN(2, 4, 0xB8001010, 0x00000004)
|
||||
//reset delay time
|
||||
DCDGEN(3, 4, 0xB8001010, 0x0000000C)
|
||||
DCDGEN(4, 4, 0xB800100C, 0x007ffc3f)
|
||||
DCDGEN(5, 4, 0xB800100C, 0x007ffc3f)
|
||||
DCDGEN(6, 4, 0xB8001004, 0x007ffc3f)
|
||||
DCDGEN(7, 4, 0xB8001000, 0x92220000)
|
||||
DCDGEN(8, 1, 0x80000400, 0xda)
|
||||
DCDGEN(9, 4, 0xB8001000, 0xA2220000)
|
||||
DCDGEN(10, 4, 0x80000000, 0x87654321)
|
||||
DCDGEN(11, 4, 0x80000000, 0x87654321)
|
||||
DCDGEN(12, 4, 0xB8001000, 0xB2220000)
|
||||
DCDGEN(13, 1, 0x80000033, 0xda)
|
||||
DCDGEN(14, 1, 0x82000000, 0xda)
|
||||
DCDGEN(15, 4, 0xB8001000, 0x82226080)
|
||||
DCDGEN(16, 4, 0xB8001010, 0x00000004)
|
||||
DCDGEN(17, 4, 0xB8001008, 0x00002000)
|
||||
|
||||
#else
|
||||
.long 240
|
||||
|
||||
//WEIM config-CS5 init
|
||||
DCDGEN(1, 4, 0xB8002050, 0x0000d843)
|
||||
DCDGEN(1_1, 4, 0xB8002054, 0x22252521)
|
||||
DCDGEN(1_2, 4, 0xB8002058, 0x22220a00)
|
||||
|
||||
//DDR2 init
|
||||
DCDGEN(2, 4, 0xB8001010, 0x00000304)
|
||||
DCDGEN(3, 4, 0xB8001010, 0x0000030C)
|
||||
DCDGEN(4, 4, 0xB8001004, 0x007ffc3f)
|
||||
DCDGEN(5, 4, 0xB8001000, 0x92220000)
|
||||
DCDGEN(6, 4, 0x80000400, 0x12345678)
|
||||
DCDGEN(7, 4, 0xB8001000, 0xA2220000)
|
||||
DCDGEN(8, 4, 0x80000000, 0x87654321)
|
||||
DCDGEN(9, 4, 0x80000000, 0x87654321)
|
||||
DCDGEN(10, 4, 0xB8001000, 0xB2220000)
|
||||
DCDGEN(11, 1, 0x80000233, 0xda)
|
||||
DCDGEN(12, 1, 0x82000780, 0xda)
|
||||
DCDGEN(13, 1, 0x82000400, 0xda)
|
||||
DCDGEN(14, 4, 0xB8001000, 0x82226080)
|
||||
DCDGEN(15, 4, 0xB8001004, 0x007ffc3f)
|
||||
DCDGEN(16, 4, 0xB800100C, 0x007ffc3f)
|
||||
DCDGEN(17, 4, 0xB8001010, 0x00000304)
|
||||
DCDGEN(18, 4, 0xB8001008, 0x00002000)
|
||||
|
||||
#endif
|
||||
dcd_data_end:
|
||||
|
||||
//CARD_FLASH_CFG_PARMS_T---length
|
||||
card_cfg: .long 0x100000
|
||||
#endif
|
||||
441
board/freescale/mx35_3stack/lowlevel_init.S
Normal file
441
board/freescale/mx35_3stack/lowlevel_init.S
Normal file
@ -0,0 +1,441 @@
|
||||
/*
|
||||
* Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
|
||||
*
|
||||
* (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include <asm/arch/mx35.h>
|
||||
#include "board-mx35_3stack.h"
|
||||
|
||||
/*
|
||||
* return soc version
|
||||
* 0x10: TO1
|
||||
* 0x20: TO2
|
||||
* 0x30: TO3
|
||||
*/
|
||||
.macro check_soc_version ret, tmp
|
||||
ldr \tmp, =IIM_BASE_ADDR
|
||||
ldr \ret, [\tmp, #IIM_SREV]
|
||||
cmp \ret, #0x00
|
||||
moveq \tmp, #ROMPATCH_REV
|
||||
ldreq \ret, [\tmp]
|
||||
moveq \ret, \ret, lsl #4
|
||||
addne \ret, \ret, #0x10
|
||||
.endm
|
||||
|
||||
/*
|
||||
* L2CC Cache setup/invalidation/disable
|
||||
*/
|
||||
.macro init_l2cc
|
||||
/* Disable L2 cache first */
|
||||
mov r0, #L2CC_BASE_ADDR
|
||||
ldr r1, [r0, #L2_CACHE_CTL_REG]
|
||||
bic r1, r1, #0x1
|
||||
str r1, [r0, #L2_CACHE_CTL_REG]
|
||||
|
||||
/*
|
||||
* Configure L2 Cache:
|
||||
* - 128k size(16k way)
|
||||
* - 8-way associativity
|
||||
* - 0 ws TAG/VALID/DIRTY
|
||||
* - 4 ws DATA R/W
|
||||
*/
|
||||
ldr r1, [r0, #L2_CACHE_AUX_CTL_REG]
|
||||
and r1, r1, #0xFE000000
|
||||
ldr r2, =L2CC_AUX_CTL_CONFIG
|
||||
orr r1, r1, r2
|
||||
str r1, [r0, #L2_CACHE_AUX_CTL_REG]
|
||||
|
||||
/* Workaournd for TO1 DDR issue:WT*/
|
||||
check_soc_version r1, r2
|
||||
cmp r1, #CHIP_REV_2_0
|
||||
ldrlo r1, [r0, #L2_CACHE_DBG_CTL_REG]
|
||||
orrlo r1, r1, #2
|
||||
strlo r1, [r0, #L2_CACHE_DBG_CTL_REG]
|
||||
|
||||
/* Invalidate L2 */
|
||||
mov r1, #0x000000FF
|
||||
str r1, [r0, #L2_CACHE_INV_WAY_REG]
|
||||
1:
|
||||
/* Poll Invalidate By Way register */
|
||||
ldr r2, [r0, #L2_CACHE_INV_WAY_REG]
|
||||
cmp r2, #0
|
||||
bne 1b
|
||||
.endm /* init_l2cc */
|
||||
|
||||
/* AIPS setup - Only setup MPROTx registers.
|
||||
* The PACR default values are good.*/
|
||||
.macro init_aips
|
||||
/*
|
||||
* Set all MPROTx to be non-bufferable, trusted for R/W,
|
||||
* not forced to user-mode.
|
||||
*/
|
||||
ldr r0, =AIPS1_BASE_ADDR
|
||||
ldr r1, =AIPS_MPR_CONFIG
|
||||
str r1, [r0, #0x00]
|
||||
str r1, [r0, #0x04]
|
||||
ldr r0, =AIPS2_BASE_ADDR
|
||||
str r1, [r0, #0x00]
|
||||
str r1, [r0, #0x04]
|
||||
|
||||
/*
|
||||
* Clear the on and off peripheral modules Supervisor Protect bit
|
||||
* for SDMA to access them. Did not change the AIPS control registers
|
||||
* (offset 0x20) access type
|
||||
*/
|
||||
ldr r0, =AIPS1_BASE_ADDR
|
||||
ldr r1, =AIPS_OPACR_CONFIG
|
||||
str r1, [r0, #0x40]
|
||||
str r1, [r0, #0x44]
|
||||
str r1, [r0, #0x48]
|
||||
str r1, [r0, #0x4C]
|
||||
str r1, [r0, #0x50]
|
||||
ldr r0, =AIPS2_BASE_ADDR
|
||||
str r1, [r0, #0x40]
|
||||
str r1, [r0, #0x44]
|
||||
str r1, [r0, #0x48]
|
||||
str r1, [r0, #0x4C]
|
||||
str r1, [r0, #0x50]
|
||||
.endm /* init_aips */
|
||||
|
||||
/* MAX (Multi-Layer AHB Crossbar Switch) setup */
|
||||
.macro init_max
|
||||
ldr r0, =MAX_BASE_ADDR
|
||||
/* MPR - priority is M4 > M2 > M3 > M5 > M0 > M1 */
|
||||
ldr r1, =MAX_MPR_CONFIG
|
||||
str r1, [r0, #0x000] /* for S0 */
|
||||
str r1, [r0, #0x100] /* for S1 */
|
||||
str r1, [r0, #0x200] /* for S2 */
|
||||
str r1, [r0, #0x300] /* for S3 */
|
||||
str r1, [r0, #0x400] /* for S4 */
|
||||
/* SGPCR - always park on last master */
|
||||
ldr r1, =MAX_SGPCR_CONFIG
|
||||
str r1, [r0, #0x010] /* for S0 */
|
||||
str r1, [r0, #0x110] /* for S1 */
|
||||
str r1, [r0, #0x210] /* for S2 */
|
||||
str r1, [r0, #0x310] /* for S3 */
|
||||
str r1, [r0, #0x410] /* for S4 */
|
||||
/* MGPCR - restore default values */
|
||||
ldr r1, =MAX_MGPCR_CONFIG
|
||||
str r1, [r0, #0x800] /* for M0 */
|
||||
str r1, [r0, #0x900] /* for M1 */
|
||||
str r1, [r0, #0xA00] /* for M2 */
|
||||
str r1, [r0, #0xB00] /* for M3 */
|
||||
str r1, [r0, #0xC00] /* for M4 */
|
||||
str r1, [r0, #0xD00] /* for M5 */
|
||||
.endm /* init_max */
|
||||
|
||||
/* M3IF setup */
|
||||
.macro init_m3if
|
||||
/* Configure M3IF registers */
|
||||
ldr r1, =M3IF_BASE_ADDR
|
||||
/*
|
||||
* M3IF Control Register (M3IFCTL)
|
||||
* MRRP[0] = L2CC0 not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[1] = L2CC1 not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[2] = MBX not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[3] = MAX1 not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[4] = SDMA not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[5] = MPEG4 not on priority list (0 << 0) = 0x00000000
|
||||
* MRRP[6] = IPU1 on priority list (1 << 6) = 0x00000040
|
||||
* MRRP[7] = IPU2 not on priority list (0 << 0) = 0x00000000
|
||||
* ------------
|
||||
* 0x00000040
|
||||
*/
|
||||
ldr r0, =M3IF_CONFIG
|
||||
str r0, [r1] /* M3IF control reg */
|
||||
.endm /* init_m3if */
|
||||
|
||||
/* To support 133MHz DDR */
|
||||
.macro init_drive_strength
|
||||
/*
|
||||
mov r0, #0x2
|
||||
ldr r1, =IOMUXC_BASE_ADDR
|
||||
add r1, r1, #0x368
|
||||
add r2, r1, #0x4C8 - 0x368
|
||||
1: str r0, [r1], #4
|
||||
cmp r1, r2
|
||||
ble 1b
|
||||
*/
|
||||
.endm /* init_drive_strength */
|
||||
|
||||
/* CPLD on CS5 setup */
|
||||
.macro init_debug_board
|
||||
ldr r0, =DBG_BASE_ADDR
|
||||
ldr r1, =DBG_CSCR_U_CONFIG
|
||||
str r1, [r0, #0x00]
|
||||
ldr r1, =DBG_CSCR_L_CONFIG
|
||||
str r1, [r0, #0x04]
|
||||
ldr r1, =DBG_CSCR_A_CONFIG
|
||||
str r1, [r0, #0x08]
|
||||
.endm /* init_debug_board */
|
||||
|
||||
/* clock setup */
|
||||
.macro init_clock
|
||||
ldr r0, =CCM_BASE_ADDR
|
||||
|
||||
/* default CLKO to 1/32 of the ARM core*/
|
||||
ldr r1, [r0, #CLKCTL_COSR]
|
||||
bic r1, r1, #0x00000FF00
|
||||
bic r1, r1, #0x0000000FF
|
||||
mov r2, #0x00006C00
|
||||
add r2, r2, #0x67
|
||||
orr r1, r1, r2
|
||||
str r1, [r0, #CLKCTL_COSR]
|
||||
|
||||
ldr r2, =CCM_CCMR_CONFIG
|
||||
str r2, [r0, #CLKCTL_CCMR]
|
||||
|
||||
check_soc_version r1, r2
|
||||
cmp r1, #CHIP_REV_2_0
|
||||
ldrhs r3, =CCM_MPLL_399_HZ
|
||||
bhs 1f
|
||||
ldr r2, [r0, #CLKCTL_PDR0]
|
||||
tst r2, #CLKMODE_CONSUMER
|
||||
ldrne r3, =CCM_MPLL_532_HZ /* consumer path*/
|
||||
ldreq r3, =CCM_MPLL_399_HZ /* auto path*/
|
||||
1:
|
||||
str r3, [r0, #CLKCTL_MPCTL]
|
||||
|
||||
ldr r1, =CCM_PPLL_300_HZ
|
||||
str r1, [r0, #CLKCTL_PPCTL]
|
||||
|
||||
ldr r1, [r0, #CLKCTL_PDR0]
|
||||
orr r1, r1, #0x800000
|
||||
str r1, [r0, #CLKCTL_PDR0]
|
||||
|
||||
ldr r1, =CCM_PDR0_CONFIG
|
||||
str r1, [r0, #CLKCTL_PDR0]
|
||||
|
||||
ldr r1, [r0, #CLKCTL_CGR0]
|
||||
orr r1, r1, #0x00300000
|
||||
str r1, [r0, #CLKCTL_CGR0]
|
||||
|
||||
ldr r1, [r0, #CLKCTL_CGR1]
|
||||
orr r1, r1, #0x00000C00
|
||||
orr r1, r1, #0x00000003
|
||||
str r1, [r0, #CLKCTL_CGR1]
|
||||
.endm /* init_clock */
|
||||
|
||||
.macro setup_sdram
|
||||
ldr r0, =ESDCTL_BASE_ADDR
|
||||
mov r3, #0x2000
|
||||
str r3, [r0, #0x0]
|
||||
str r3, [r0, #0x8]
|
||||
|
||||
/*ip(r12) has used to save lr register in upper calling*/
|
||||
mov fp, lr
|
||||
|
||||
mov r5, #0x00
|
||||
mov r2, #0x00
|
||||
mov r1, #CSD0_BASE_ADDR
|
||||
bl setup_sdram_bank
|
||||
cmp r3, #0x0
|
||||
orreq r5, r5, #1
|
||||
eorne r2, r2, #0x1
|
||||
blne setup_sdram_bank
|
||||
|
||||
mov lr, fp
|
||||
|
||||
check_soc_version r3, r4
|
||||
cmp r1, #CHIP_REV_2_0
|
||||
bhs 1f
|
||||
cmp r5, #0
|
||||
movne r3, #L2CC_BASE_ADDR
|
||||
ldrne r4, [r3, #L2_CACHE_AUX_CTL_REG]
|
||||
orrne r4, r4, #0x1000
|
||||
strne r4, [r3, #L2_CACHE_AUX_CTL_REG]
|
||||
1:
|
||||
ldr r3, =ESDCTL_DELAY_LINE5
|
||||
str r3, [r0, #0x30]
|
||||
.endm /* setup_sdram */
|
||||
|
||||
.section ".text.init", "x"
|
||||
|
||||
.globl lowlevel_init
|
||||
lowlevel_init:
|
||||
/* Platform CHIP level init*/
|
||||
#ifdef TURN_OFF_IMPRECISE_ABORT
|
||||
mrs r0, cpsr
|
||||
bic r0, r0, #0x100
|
||||
msr cpsr, r0
|
||||
#endif
|
||||
|
||||
mrc 15, 0, r1, c1, c0, 0
|
||||
|
||||
#ifndef BRANCH_PREDICTION_ENABLE
|
||||
mrc 15, 0, r0, c1, c0, 1
|
||||
bic r0, r0, #7
|
||||
mcr 15, 0, r0, c1, c0, 1
|
||||
#else
|
||||
mrc 15, 0, r0, c1, c0, 1
|
||||
orr r0, r0, #7
|
||||
mcr 15, 0, r0, c1, c0, 1
|
||||
orr r1, r1, #(1<<11)
|
||||
#endif
|
||||
|
||||
#ifdef UNALIGNED_ACCESS_ENABLE
|
||||
orr r1, r1, #(1<<22)
|
||||
#endif
|
||||
|
||||
#ifdef LOW_INT_LATENCY_ENABLE
|
||||
orr r1, r1, #(1<<21)
|
||||
#endif
|
||||
mcr 15, 0, r1, c1, c0, 0
|
||||
|
||||
mov r0, #0
|
||||
#ifdef BRANCH_PREDICTION_ENABLE
|
||||
mcr 15, 0, r0, c15, c2, 4
|
||||
#endif
|
||||
mcr 15, 0, r0, c7, c10, 4 /* Drain the write buffer */
|
||||
|
||||
/* initializes very early AIPS, what for?
|
||||
* Then it also initializes Multi-Layer AHB Crossbar Switch,
|
||||
* M3IF */
|
||||
/* Also setup the Peripheral Port Remap register inside the core */
|
||||
ldr r0, =0x40000015 /* start from AIPS 2GB region */
|
||||
mcr p15, 0, r0, c15, c2, 4
|
||||
|
||||
init_l2cc
|
||||
|
||||
init_aips
|
||||
|
||||
init_max
|
||||
|
||||
init_m3if
|
||||
|
||||
init_drive_strength
|
||||
|
||||
cmp pc, #PHYS_SDRAM_1
|
||||
blo init_clock_start
|
||||
cmp pc, #(PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)
|
||||
blo skip_sdram_setup
|
||||
|
||||
init_clock_start:
|
||||
init_clock
|
||||
init_debug_board
|
||||
/*init_sdram*/
|
||||
setup_sdram
|
||||
skip_sdram_setup:
|
||||
mov r0, #NFC_BASE_ADDR
|
||||
add r1, r0, #NFC_BUF_SIZE
|
||||
cmp pc, r0
|
||||
movlo pc, lr
|
||||
cmp pc, r1
|
||||
movhi pc, lr
|
||||
/* return from mxc_nand_load */
|
||||
/* r12 saved upper lr*/
|
||||
b mxc_nand_load
|
||||
|
||||
/*
|
||||
* r0: ESDCTL control base, r1: sdram slot base
|
||||
* r2: DDR type(0:DDR2, 1:MDDR) r3, r4:working base
|
||||
*/
|
||||
setup_sdram_bank:
|
||||
mov r3, #0xE /*0xA + 0x4*/
|
||||
tst r2, #0x1
|
||||
orreq r3, r3, #0x300 /*DDR2*/
|
||||
str r3, [r0, #0x10]
|
||||
bic r3, r3, #0x00A
|
||||
str r3, [r0, #0x10]
|
||||
beq 2f
|
||||
|
||||
mov r3, #0x20000
|
||||
1: subs r3, r3, #1
|
||||
bne 1b
|
||||
|
||||
2: tst r2, #0x1
|
||||
ldreq r3, =ESDCTL_DDR2_CONFIG
|
||||
ldrne r3, =ESDCTL_MDDR_CONFIG
|
||||
cmp r1, #CSD1_BASE_ADDR
|
||||
strlo r3, [r0, #0x4]
|
||||
strhs r3, [r0, #0xC]
|
||||
|
||||
ldr r3, =ESDCTL_0x92220000
|
||||
strlo r3, [r0, #0x0]
|
||||
strhs r3, [r0, #0x8]
|
||||
mov r3, #0xDA
|
||||
ldr r4, =ESDCTL_PRECHARGE
|
||||
strb r3, [r1, r4]
|
||||
|
||||
tst r2, #0x1
|
||||
bne skip_set_mode
|
||||
|
||||
cmp r1, #CSD1_BASE_ADDR
|
||||
ldr r3, =ESDCTL_0xB2220000
|
||||
strlo r3, [r0, #0x0]
|
||||
strhs r3, [r0, #0x8]
|
||||
mov r3, #0xDA
|
||||
ldr r4, =ESDCTL_DDR2_EMR2
|
||||
strb r3, [r1, r4]
|
||||
ldr r4, =ESDCTL_DDR2_EMR3
|
||||
strb r3, [r1, r4]
|
||||
ldr r4, =ESDCTL_DDR2_EN_DLL
|
||||
strb r3, [r1, r4]
|
||||
ldr r4, =ESDCTL_DDR2_RESET_DLL
|
||||
strb r3, [r1, r4]
|
||||
|
||||
ldr r3, =ESDCTL_0x92220000
|
||||
strlo r3, [r0, #0x0]
|
||||
strhs r3, [r0, #0x8]
|
||||
mov r3, #0xDA
|
||||
ldr r4, =ESDCTL_PRECHARGE
|
||||
strb r3, [r1, r4]
|
||||
|
||||
skip_set_mode:
|
||||
cmp r1, #CSD1_BASE_ADDR
|
||||
ldr r3, =ESDCTL_0xA2220000
|
||||
strlo r3, [r0, #0x0]
|
||||
strhs r3, [r0, #0x8]
|
||||
mov r3, #0xDA
|
||||
strb r3, [r1]
|
||||
strb r3, [r1]
|
||||
|
||||
ldr r3, =ESDCTL_0xB2220000
|
||||
strlo r3, [r0, #0x0]
|
||||
strhs r3, [r0, #0x8]
|
||||
tst r2, #0x1
|
||||
ldreq r4, =ESDCTL_DDR2_MR
|
||||
ldrne r4, =ESDCTL_MDDR_MR
|
||||
mov r3, #0xDA
|
||||
strb r3, [r1, r4]
|
||||
ldreq r4, =ESDCTL_DDR2_OCD_DEFAULT
|
||||
streqb r3, [r1, r4]
|
||||
ldreq r4, =ESDCTL_DDR2_EN_DLL
|
||||
ldrne r4, =ESDCTL_MDDR_EMR
|
||||
strb r3, [r1, r4]
|
||||
|
||||
cmp r1, #CSD1_BASE_ADDR
|
||||
ldr r3, =ESDCTL_0x82228080
|
||||
strlo r3, [r0, #0x0]
|
||||
strhs r3, [r0, #0x8]
|
||||
|
||||
tst r2, #0x1
|
||||
moveq r4, #0x20000
|
||||
movne r4, #0x200
|
||||
1: subs r4, r4, #1
|
||||
bne 1b
|
||||
|
||||
str r3, [r1, #0x100]
|
||||
ldr r4, [r1, #0x100]
|
||||
cmp r3, r4
|
||||
movne r3, #1
|
||||
moveq r3, #0
|
||||
|
||||
mov pc, lr
|
||||
402
board/freescale/mx35_3stack/mx35_3stack.c
Normal file
402
board/freescale/mx35_3stack/mx35_3stack.c
Normal file
@ -0,0 +1,402 @@
|
||||
/*
|
||||
* Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
|
||||
*
|
||||
* (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/arch/mx35.h>
|
||||
#include <asm/arch/mx35_pins.h>
|
||||
#include <asm/arch/iomux.h>
|
||||
#include <i2c.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
volatile u32 *esdhc_base_pointer;
|
||||
|
||||
static u32 system_rev;
|
||||
|
||||
u32 get_board_rev(void)
|
||||
{
|
||||
return system_rev;
|
||||
}
|
||||
|
||||
static inline void setup_soc_rev(void)
|
||||
{
|
||||
int reg;
|
||||
reg = __REG(IIM_BASE_ADDR + IIM_SREV);
|
||||
if (!reg) {
|
||||
reg = __REG(ROMPATCH_REV);
|
||||
reg <<= 4;
|
||||
} else
|
||||
reg += CHIP_REV_1_0;
|
||||
system_rev = 0x35000 + (reg & 0xFF);
|
||||
}
|
||||
|
||||
static inline void set_board_rev(int rev)
|
||||
{
|
||||
int reg;
|
||||
system_rev = (system_rev & ~(0xF << 8)) | (rev & 0xF) << 8;
|
||||
}
|
||||
|
||||
int is_soc_rev(int rev)
|
||||
{
|
||||
return (system_rev & 0xFF) - rev;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
|
||||
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
int pad;
|
||||
|
||||
setup_soc_rev();
|
||||
|
||||
/* enable clocks */
|
||||
__REG(CCM_BASE_ADDR + CLKCTL_CGR0) |= 0x003F0000;
|
||||
__REG(CCM_BASE_ADDR + CLKCTL_CGR1) |= 0x00030FFF;
|
||||
|
||||
/* setup pins for I2C1 */
|
||||
mxc_request_iomux(MX35_PIN_I2C1_CLK, MUX_CONFIG_SION);
|
||||
mxc_request_iomux(MX35_PIN_I2C1_DAT, MUX_CONFIG_SION);
|
||||
|
||||
pad = (PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE \
|
||||
| PAD_CTL_PUE_PUD | PAD_CTL_ODE_OpenDrain);
|
||||
|
||||
mxc_iomux_set_pad(MX35_PIN_I2C1_CLK, pad);
|
||||
mxc_iomux_set_pad(MX35_PIN_I2C1_DAT, pad);
|
||||
|
||||
/* setup pins for FEC */
|
||||
mxc_request_iomux(MX35_PIN_FEC_TX_CLK, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_RX_CLK, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_RX_DV, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_COL, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_RDATA0, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_TDATA0, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_TX_EN, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_MDC, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_MDIO, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_TX_ERR, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_RX_ERR, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_CRS, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_RDATA1, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_TDATA1, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_RDATA2, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_TDATA2, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_RDATA3, MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_FEC_TDATA3, MUX_CONFIG_FUNC);
|
||||
|
||||
pad = (PAD_CTL_DRV_3_3V | PAD_CTL_PUE_PUD | PAD_CTL_ODE_CMOS | \
|
||||
PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW);
|
||||
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_TX_CLK, pad | PAD_CTL_HYS_SCHMITZ | \
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_RX_CLK, pad | PAD_CTL_HYS_SCHMITZ | \
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_RX_DV, pad | PAD_CTL_HYS_SCHMITZ | \
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_COL, pad | PAD_CTL_HYS_SCHMITZ | \
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_RDATA0, pad | PAD_CTL_HYS_SCHMITZ | \
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_TDATA0, pad | PAD_CTL_HYS_CMOS | \
|
||||
PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_TX_EN, pad | PAD_CTL_HYS_CMOS | \
|
||||
PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_MDC, pad | PAD_CTL_HYS_CMOS | \
|
||||
PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_MDIO, pad | PAD_CTL_HYS_SCHMITZ | \
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_22K_PU);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_TX_ERR, pad | PAD_CTL_HYS_CMOS | \
|
||||
PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_RX_ERR, pad | PAD_CTL_HYS_SCHMITZ | \
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_CRS, pad | PAD_CTL_HYS_SCHMITZ | \
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_RDATA1, pad | PAD_CTL_HYS_SCHMITZ | \
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_TDATA1, pad | PAD_CTL_HYS_CMOS | \
|
||||
PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_RDATA2, pad | PAD_CTL_HYS_SCHMITZ | \
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_TDATA2, pad | PAD_CTL_HYS_CMOS | \
|
||||
PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_RDATA3, pad | PAD_CTL_HYS_SCHMITZ | \
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
|
||||
mxc_iomux_set_pad(MX35_PIN_FEC_TDATA3, pad | PAD_CTL_HYS_CMOS | \
|
||||
PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
|
||||
|
||||
gd->bd->bi_arch_number = MACH_TYPE_MX35_3DS; /* board id for linux */
|
||||
gd->bd->bi_boot_params = 0x80000100; /* address of boot parameters */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef BOARD_LATE_INIT
|
||||
static inline int board_detect(void)
|
||||
{
|
||||
u8 buf[4];
|
||||
int id;
|
||||
|
||||
if (i2c_read(0x08, 0x7, 1, buf, 3) < 0) {
|
||||
printf("board_late_init: read PMIC@0x08:0x7 fail\n");
|
||||
return 0;
|
||||
}
|
||||
id = (buf[0] << 16) + (buf[1] << 8) + buf[2];
|
||||
printf("PMIC@0x08:0x7 is %x\n", id);
|
||||
id = (id >> 6) & 0x7;
|
||||
if (id == 0x7) {
|
||||
set_board_rev(1);
|
||||
return 1;
|
||||
}
|
||||
set_board_rev(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_late_init(void)
|
||||
{
|
||||
u8 reg[3];
|
||||
int i;
|
||||
|
||||
if (board_detect()) {
|
||||
mxc_request_iomux(MX35_PIN_WATCHDOG_RST, MUX_CONFIG_SION |
|
||||
MUX_CONFIG_ALT1);
|
||||
printf("i.MX35 CPU board version 2.0\n");
|
||||
if (i2c_read(0x08, 0x1E, 1, reg, 3)) {
|
||||
printf("board_late_init: read PMIC@0x08:0x1E fail\n");
|
||||
return 0;
|
||||
}
|
||||
reg[2] |= 0x3;
|
||||
if (i2c_write(0x08, 0x1E, 1, reg, 3)) {
|
||||
printf("board_late_init: write PMIC@0x08:0x1E fail\n");
|
||||
return 0;
|
||||
}
|
||||
if (i2c_read(0x08, 0x20, 1, reg, 3)) {
|
||||
printf("board_late_init: read PMIC@0x08:0x20 fail\n");
|
||||
return 0;
|
||||
}
|
||||
reg[2] |= 0x1;
|
||||
if (i2c_write(0x08, 0x20, 1, reg, 3)) {
|
||||
printf("board_late_init: write PMIC@0x08:0x20 fail\n");
|
||||
return 0;
|
||||
}
|
||||
mxc_request_iomux(MX35_PIN_COMPARE, MUX_CONFIG_GPIO);
|
||||
mxc_iomux_set_input(MUX_IN_GPIO1_IN_5, INPUT_CTL_PATH0);
|
||||
__REG(GPIO1_BASE_ADDR + 0x04) |= 1 << 5;
|
||||
__REG(GPIO1_BASE_ADDR) |= 1 << 5;
|
||||
} else
|
||||
printf("i.MX35 CPU board version 1.0\n");
|
||||
|
||||
if (i2c_read(0x69, 0x20, 1, reg, 1) < 0) {
|
||||
printf("board_late_init: read PMIC@0x69:0x20 fail\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
reg[0] |= 0x4;
|
||||
if (i2c_write(0x69, 0x20, 1, reg, 1) < 0) {
|
||||
printf("board_late_init: write back PMIC@0x69:0x20 fail\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 1000; i++)
|
||||
udelay(200);
|
||||
|
||||
if (i2c_read(0x69, 0x1A, 1, reg, 1) < 0) {
|
||||
printf("board_late_init: read PMIC@0x69:0x1A fail\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
reg[0] &= 0x7F;
|
||||
if (i2c_write(0x69, 0x1A, 1, reg, 1) < 0) {
|
||||
printf("board_late_init: write back PMIC@0x69:0x1A fail\n");
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < 1000; i++)
|
||||
udelay(200);
|
||||
|
||||
reg[0] |= 0x80;
|
||||
if (i2c_write(0x69, 0x1A, 1, reg, 1) < 0) {
|
||||
printf("board_late_init: 2st write back PMIC@0x69:0x1A fail\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
printf("Board: MX35 3STACK [");
|
||||
switch (__REG(CCM_BASE_ADDR + CLKCTL_RCSR) & 0x0F) {
|
||||
case 0x0000:
|
||||
printf("POR");
|
||||
break;
|
||||
case 0x0002:
|
||||
printf("JTAG");
|
||||
break;
|
||||
case 0x0004:
|
||||
printf("RST");
|
||||
break;
|
||||
case 0x0008:
|
||||
printf("WDT");
|
||||
break;
|
||||
default:
|
||||
printf("unknown");
|
||||
}
|
||||
printf("]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_eth_init(bd_t *bis)
|
||||
{
|
||||
int rc = -ENODEV;
|
||||
#if defined(CONFIG_DRIVER_SMC911X)
|
||||
rc = smc911x_initialize(bis);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FSL_MMC
|
||||
|
||||
int sdhc_init(void)
|
||||
{
|
||||
u32 interface_esdhc = 0;
|
||||
u32 pad_val = 0;
|
||||
|
||||
interface_esdhc = (readl(IIM_BASE_ADDR + 0x80c)) & (0x000000C0) >> 6;
|
||||
|
||||
if (!is_soc_rev(CHIP_REV_1_0)) {
|
||||
pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
|
||||
PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_MAX |
|
||||
PAD_CTL_100K_PU | PAD_CTL_SRE_FAST;
|
||||
|
||||
switch (interface_esdhc) {
|
||||
case 0:
|
||||
debug("TO1 ESDHC1\n");
|
||||
|
||||
esdhc_base_pointer = \
|
||||
(volatile u32 *)MMC_SDHC1_BASE_ADDR;
|
||||
|
||||
mxc_iomux_set_pad(MX35_PIN_SD1_DATA3, pad_val);
|
||||
break;
|
||||
case 1:
|
||||
debug("TO1 ESDHC2\n");
|
||||
|
||||
esdhc_base_pointer = \
|
||||
(volatile u32 *)MMC_SDHC2_BASE_ADDR;
|
||||
|
||||
mxc_iomux_set_pad(MX35_PIN_SD2_DATA3, pad_val);
|
||||
break;
|
||||
case 2:
|
||||
debug("TO1 ESDHC3\n");
|
||||
|
||||
esdhc_base_pointer = \
|
||||
(volatile u32 *)MMC_SDHC3_BASE_ADDR;
|
||||
|
||||
printf("TO1 ESDHC3 not supported!");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (!is_soc_rev(CHIP_REV_2_0)) {
|
||||
/* IOMUX PROGRAMMING */
|
||||
switch (interface_esdhc) {
|
||||
case 0:
|
||||
debug("TO2 ESDHC1\n");
|
||||
|
||||
esdhc_base_pointer = \
|
||||
(volatile u32 *)MMC_SDHC1_BASE_ADDR;
|
||||
|
||||
pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
|
||||
PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_HIGH |
|
||||
PAD_CTL_47K_PU | PAD_CTL_SRE_FAST;
|
||||
mxc_request_iomux(MX35_PIN_SD1_CLK,
|
||||
MUX_CONFIG_FUNC | MUX_CONFIG_SION);
|
||||
mxc_iomux_set_pad(MX35_PIN_SD1_CLK, pad_val);
|
||||
|
||||
pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
|
||||
PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_HIGH |
|
||||
PAD_CTL_100K_PU | PAD_CTL_SRE_FAST;
|
||||
mxc_request_iomux(MX35_PIN_SD1_CMD,
|
||||
MUX_CONFIG_FUNC | MUX_CONFIG_SION);
|
||||
mxc_iomux_set_pad(MX35_PIN_SD1_CMD, pad_val);
|
||||
mxc_request_iomux(MX35_PIN_SD1_DATA0,
|
||||
MUX_CONFIG_FUNC);
|
||||
mxc_iomux_set_pad(MX35_PIN_SD1_DATA0, pad_val);
|
||||
mxc_request_iomux(MX35_PIN_SD1_DATA3,
|
||||
MUX_CONFIG_FUNC);
|
||||
mxc_iomux_set_pad(MX35_PIN_SD1_DATA3, pad_val);
|
||||
|
||||
break;
|
||||
case 1:
|
||||
debug("TO2 ESDHC2\n");
|
||||
|
||||
esdhc_base_pointer = \
|
||||
(volatile u32 *)MMC_SDHC2_BASE_ADDR;
|
||||
|
||||
mxc_request_iomux(MX35_PIN_SD2_CLK,
|
||||
MUX_CONFIG_FUNC | MUX_CONFIG_SION);
|
||||
mxc_request_iomux(MX35_PIN_SD2_CMD,
|
||||
MUX_CONFIG_FUNC | MUX_CONFIG_SION);
|
||||
mxc_request_iomux(MX35_PIN_SD2_DATA0,
|
||||
MUX_CONFIG_FUNC);
|
||||
mxc_request_iomux(MX35_PIN_SD2_DATA3,
|
||||
MUX_CONFIG_FUNC);
|
||||
|
||||
pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
|
||||
PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_MAX |
|
||||
PAD_CTL_47K_PU | PAD_CTL_SRE_FAST;
|
||||
mxc_iomux_set_pad(MX35_PIN_SD2_CLK, pad_val);
|
||||
|
||||
pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
|
||||
PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_MAX |
|
||||
PAD_CTL_100K_PU | PAD_CTL_SRE_FAST;
|
||||
mxc_iomux_set_pad(MX35_PIN_SD2_CMD, pad_val);
|
||||
mxc_iomux_set_pad(MX35_PIN_SD2_DATA0, pad_val);
|
||||
mxc_iomux_set_pad(MX35_PIN_SD2_DATA3, pad_val);
|
||||
|
||||
break;
|
||||
case 2:
|
||||
debug("TO2 ESDHC3\n");
|
||||
|
||||
esdhc_base_pointer = \
|
||||
(volatile u32 *)MMC_SDHC3_BASE_ADDR;
|
||||
|
||||
printf("TO2 ESDHC3 not supported!");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
77
board/freescale/mx35_3stack/u-boot.lds
Normal file
77
board/freescale/mx35_3stack/u-boot.lds
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* January 2004 - Changed to support H4 device
|
||||
* Copyright (c) 2004 Texas Instruments
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
|
||||
*
|
||||
* (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
/* WARNING - the following is hand-optimized to fit within */
|
||||
/* the sector layout of our flash chips! XXX FIXME XXX */
|
||||
board/freescale/mx35_3stack/flash_header.o (.text.flasheader)
|
||||
*(.text.head) /*arm startup code*/
|
||||
*(.text.init) /*platform lowlevel initial code*/
|
||||
*(.text.load) /*load bootloader*/
|
||||
*(.text.setup) /*platform post lowlevel initial code*/
|
||||
*(.text.vect) /*platform post lowlevel initial code*/
|
||||
board/freescale/mx35_3stack/libmx35_3stack.a (.text)
|
||||
lib_arm/libarm.a (.text)
|
||||
net/libnet.a (.text)
|
||||
drivers/mtd/libmtd.a (.text)
|
||||
drivers/mmc/libmmc.a (.text)
|
||||
|
||||
. = DEFINED(env_offset) ? env_offset : .;
|
||||
common/env_embedded.o(.text)
|
||||
|
||||
*(.text)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(.rodata) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : { *(.data) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.got : { *(.got) }
|
||||
|
||||
. = .;
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
.bss : { *(.bss) }
|
||||
_end = .;
|
||||
}
|
||||
49
board/freescale/mx51_3stack/Makefile
Normal file
49
board/freescale/mx51_3stack/Makefile
Normal file
@ -0,0 +1,49 @@
|
||||
#
|
||||
# Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
|
||||
#
|
||||
# (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
#
|
||||
# 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$(BOARD).a
|
||||
|
||||
COBJS := mx51_3stack.o
|
||||
SOBJS := lowlevel_init.o flash_header.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
SOBJS := $(addprefix $(obj),$(SOBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS) $(SOBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
64
board/freescale/mx51_3stack/board-mx51_3stack.h
Normal file
64
board/freescale/mx51_3stack/board-mx51_3stack.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#ifndef __BOARD_FREESCALE_BOARD_MX51_3STACK_H__
|
||||
#define __BOARD_FREESCALE_BOARD_MX51_3STACK_H__
|
||||
|
||||
/*!
|
||||
* @defgroup BRDCFG_MX51 Board Configuration Options
|
||||
* @ingroup MSL_MX51
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file mx51_3stack/board-mx51_3stack.h
|
||||
*
|
||||
* @brief This file contains all the board level configuration options.
|
||||
*
|
||||
* It currently hold the options defined for MX51 3Stack Platform.
|
||||
*
|
||||
* @ingroup BRDCFG_MX51
|
||||
*/
|
||||
|
||||
/* CPLD offsets */
|
||||
#define PBC_LED_CTRL (0x20000)
|
||||
#define PBC_SB_STAT (0x20008)
|
||||
#define PBC_ID_AAAA (0x20040)
|
||||
#define PBC_ID_5555 (0x20048)
|
||||
#define PBC_VERSION (0x20050)
|
||||
#define PBC_ID_CAFE (0x20058)
|
||||
#define PBC_INT_STAT (0x20010)
|
||||
#define PBC_INT_MASK (0x20038)
|
||||
#define PBC_INT_REST (0x20020)
|
||||
#define PBC_SW_RESET (0x20060)
|
||||
|
||||
/* LED switchs */
|
||||
#define LED_SWITCH_REG 0x00
|
||||
/* buttons */
|
||||
#define SWITCH_BUTTONS_REG 0x08
|
||||
/* status, interrupt */
|
||||
#define INTR_STATUS_REG 0x10
|
||||
#define INTR_MASK_REG 0x38
|
||||
#define INTR_RESET_REG 0x20
|
||||
/* magic word for debug CPLD */
|
||||
#define MAGIC_NUMBER1_REG 0x40
|
||||
#define MAGIC_NUMBER2_REG 0x48
|
||||
/* CPLD code version */
|
||||
#define CPLD_CODE_VER_REG 0x50
|
||||
/* magic word for debug CPLD */
|
||||
#define MAGIC_NUMBER3_REG 0x58
|
||||
/* module reset register*/
|
||||
#define MODULE_RESET_REG 0x60
|
||||
/* CPU ID and Personality ID */
|
||||
#define MCU_BOARD_ID_REG 0x68
|
||||
|
||||
#endif /* __BOARD_FREESCALE_BOARD_MX51_3STACK_H__ */
|
||||
1
board/freescale/mx51_3stack/config.mk
Normal file
1
board/freescale/mx51_3stack/config.mk
Normal file
@ -0,0 +1 @@
|
||||
TEXT_BASE = 0x97800000
|
||||
164
board/freescale/mx51_3stack/flash_header.S
Normal file
164
board/freescale/mx51_3stack/flash_header.S
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include <asm/arch/mx51.h>
|
||||
#include "board-mx51_3stack.h"
|
||||
|
||||
#ifdef CONFIG_FLASH_HEADER
|
||||
#ifndef CONFIG_FLASH_HEADER_OFFSET
|
||||
# error "Must define the offset of flash header"
|
||||
#endif
|
||||
#define MXC_DCD_ITEM(i, type, addr, val) \
|
||||
dcd_node_##i: \
|
||||
.word type ; \
|
||||
.word addr ; \
|
||||
.word val ; \
|
||||
|
||||
.section ".text.flasheader", "x"
|
||||
b _start
|
||||
.org CONFIG_FLASH_HEADER_OFFSET
|
||||
app_code_jump_v: .word _start
|
||||
app_code_code_barker: .word CONFIG_FLASH_HEADER_BARKER
|
||||
app_code_csf: .word 0
|
||||
dcd_ptr_ptr: .word dcd_ptr
|
||||
super_root_key: .word 0
|
||||
dcd_ptr: .word dcd_array_start
|
||||
app_dest_ptr: .word TEXT_BASE
|
||||
dcd_array_start:
|
||||
magic: .word 0xB17219E9
|
||||
dcd_array_size: .word dcd_data_end - dcd_array_start - 8
|
||||
/* DCD */
|
||||
#ifdef CONFIG_IMX51_MDDR
|
||||
/* Control, Data, Address pads are in their default state: HIGH DS, FAST SR.*/
|
||||
+MXC_DCD_ITEM(1, 4, IOMUXC_BASE_ADDR + 0x4b8, 0x000000e7) /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK MAX DS */
|
||||
+MXC_DCD_ITEM(2, 4, IOMUXC_BASE_ADDR + 0x4d4, 0x000000e4) /* DQM0 DS high, slew rate slow */
|
||||
+MXC_DCD_ITEM(3, 4, IOMUXC_BASE_ADDR + 0x4d8, 0x000000e4) /* DQM1 DS high, slew rate slow */
|
||||
+MXC_DCD_ITEM(4, 4, IOMUXC_BASE_ADDR + 0x4dc, 0x000000e4) /* DQM2 DS high, slew rate slow */
|
||||
+MXC_DCD_ITEM(5, 4, IOMUXC_BASE_ADDR + 0x4e0, 0x000000e4) /* DQM3 DS high, slew rate slow */
|
||||
+MXC_DCD_ITEM(6, 4, IOMUXC_BASE_ADDR + 0x4bc, 0x000000c4) /* SDQS0 DS high, slew rate slow */
|
||||
+MXC_DCD_ITEM(7, 4, IOMUXC_BASE_ADDR + 0x4c0, 0x000000c4) /* SDQS1 DS high, slew rate slow */
|
||||
+MXC_DCD_ITEM(8, 4, IOMUXC_BASE_ADDR + 0x4c4, 0x000000c4) /* SDQS2 DS high, slew rate slow */
|
||||
+MXC_DCD_ITEM(9, 4, IOMUXC_BASE_ADDR + 0x4c8, 0x000000c4) /* SDQS3 DS high, slew rate slow */
|
||||
+MXC_DCD_ITEM(10, 4, IOMUXC_BASE_ADDR + 0x8a4, 0x00000004) /* DRAM_B0 */
|
||||
+MXC_DCD_ITEM(11, 4, IOMUXC_BASE_ADDR + 0x8ac, 0x00000004) /* DRAM_B1 */
|
||||
+MXC_DCD_ITEM(12, 4, IOMUXC_BASE_ADDR + 0x8b8, 0x00000004) /* DRAM_B2 */
|
||||
+MXC_DCD_ITEM(13, 4, IOMUXC_BASE_ADDR + 0x82c, 0x00000004) /* DRAM_B3 */
|
||||
+MXC_DCD_ITEM(14, 4, IOMUXC_BASE_ADDR + 0x878, 0x00000000) /* DRAM_B0_SR */
|
||||
+MXC_DCD_ITEM(15, 4, IOMUXC_BASE_ADDR + 0x880, 0x00000000) /* DRAM_B1_SR */
|
||||
+MXC_DCD_ITEM(16, 4, IOMUXC_BASE_ADDR + 0x88c, 0x00000000) /* DRAM_B2_SR */
|
||||
+MXC_DCD_ITEM(17, 4, IOMUXC_BASE_ADDR + 0x89c, 0x00000000) /* DRAM_B3_SR */
|
||||
+// Configure CS0
|
||||
+MXC_DCD_ITEM(18, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCTL0, 0x83220000) /* ESDCTL0: Enable controller */
|
||||
+MXC_DCD_ITEM(19, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x04008008) /* ESDSCR: Precharge command */
|
||||
+MXC_DCD_ITEM(20, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008010) /* ESDSCR: Refresh command */
|
||||
+MXC_DCD_ITEM(21, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008010) /* ESDSCR: Refresh command */
|
||||
+MXC_DCD_ITEM(22, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00338018) /* ESDSCR: LMR with CAS=3 and BL=3 (Burst Length = 8) */
|
||||
+MXC_DCD_ITEM(23, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0060801a) /* ESDSCR: EMR with Half Drive strength */
|
||||
+MXC_DCD_ITEM(24, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008000) /* ESDSCR */
|
||||
+MXC_DCD_ITEM(25, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCTL0, 0xC3220000) /* ESDCTL0: 14 ROW, 10 COL, 32Bit, SREF=8 */
|
||||
+/* ESDCFG0: tRFC:22clks, tXSR:28clks, tXP:2clks, tWTR:2clk, tRP:3clks, tMRD:2clks
|
||||
+/* tRAS:8clks, tRRD:2clks, tWR:3clks, tRCD:3clks, tRC:11clks */
|
||||
+MXC_DCD_ITEM(26, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCFG0, 0xC33574AA)
|
||||
+MXC_DCD_ITEM(27, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDMISC, 0x000a1700) /* ESDMISC: AP=10, Bank interleaving on, MIF3 en, RALAT=2 */
|
||||
+/* Configure CS1 */
|
||||
+MXC_DCD_ITEM(28, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCTL1, 0x83220000) /* ESDCTL1: Enable controller */
|
||||
+MXC_DCD_ITEM(29, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0400800c) /* ESDSCR: Precharge command */
|
||||
+MXC_DCD_ITEM(30, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008014) /* ESDSCR: Refresh command */
|
||||
+MXC_DCD_ITEM(31, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008014) /* ESDSCR: Refresh command */
|
||||
+MXC_DCD_ITEM(32, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0033801c) /* ESDSCR: LMR with CAS=3 and BL=3 (Burst Length = 8) */
|
||||
+MXC_DCD_ITEM(33, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0060801e) /* ESDSCR: EMR with Half Drive strength */
|
||||
+MXC_DCD_ITEM(34, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008004) /* ESDSCR */
|
||||
+MXC_DCD_ITEM(35, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCTL1, 0xC3220000) /* ESDCTL1: 14 ROW, 10 COL, 32Bit, SREF=8 */
|
||||
+/* ESDCFG0: tRFC:22clks, tXSR:28clks, tXP:2clks, tWTR:2clk, tRP:3clks, tMRD:2clks */
|
||||
+/* tRAS:8clks, tRRD:2clks, tWR:3clks, tRCD:3clks, tRC:11clks */
|
||||
+MXC_DCD_ITEM(36, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCFG1, 0xC33574AA)
|
||||
+MXC_DCD_ITEM(37, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00000000) /* ESDSCR - clear "configuration request" bit */
|
||||
+MXC_DCD_ITEM(38, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCDLY5, 0x00f58000) /*Delay line write - -11 */
|
||||
#else
|
||||
/* DDR2 IOMUX configuration */
|
||||
MXC_DCD_ITEM(1, 4, IOMUXC_BASE_ADDR + 0x8a0, 0x200)
|
||||
MXC_DCD_ITEM(2, 4, IOMUXC_BASE_ADDR + 0x50c, 0x20c5)
|
||||
MXC_DCD_ITEM(3, 4, IOMUXC_BASE_ADDR + 0x510, 0x20c5)
|
||||
MXC_DCD_ITEM(4, 4, IOMUXC_BASE_ADDR + 0x83c, 0x2)
|
||||
MXC_DCD_ITEM(5, 4, IOMUXC_BASE_ADDR + 0x848, 0x2)
|
||||
MXC_DCD_ITEM(6, 4, IOMUXC_BASE_ADDR + 0x4b8, 0xe7)
|
||||
MXC_DCD_ITEM(7, 4, IOMUXC_BASE_ADDR + 0x4bc, 0x45)
|
||||
MXC_DCD_ITEM(8, 4, IOMUXC_BASE_ADDR + 0x4c0, 0x45)
|
||||
MXC_DCD_ITEM(9, 4, IOMUXC_BASE_ADDR + 0x4c4, 0x45)
|
||||
MXC_DCD_ITEM(10, 4, IOMUXC_BASE_ADDR + 0x4c8, 0x45)
|
||||
MXC_DCD_ITEM(11, 4, IOMUXC_BASE_ADDR + 0x820, 0x0)
|
||||
MXC_DCD_ITEM(12, 4, IOMUXC_BASE_ADDR + 0x4a4, 0x3)
|
||||
MXC_DCD_ITEM(13, 4, IOMUXC_BASE_ADDR + 0x4a8, 0x3)
|
||||
MXC_DCD_ITEM(14, 4, IOMUXC_BASE_ADDR + 0x4ac, 0xe3)
|
||||
MXC_DCD_ITEM(15, 4, IOMUXC_BASE_ADDR + 0x4b0, 0xe3)
|
||||
MXC_DCD_ITEM(16, 4, IOMUXC_BASE_ADDR + 0x4b4, 0xe3)
|
||||
MXC_DCD_ITEM(17, 4, IOMUXC_BASE_ADDR + 0x4cc, 0xe3)
|
||||
MXC_DCD_ITEM(18, 4, IOMUXC_BASE_ADDR + 0x4d0, 0xe2)
|
||||
/* 13 ROW, 10 COL, 32Bit, SREF=4 Micron Model */
|
||||
/* CAS=3, BL=4 */
|
||||
MXC_DCD_ITEM(19, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCTL0, 0x82a20000)
|
||||
MXC_DCD_ITEM(20, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCTL1, 0x82a20000)
|
||||
MXC_DCD_ITEM(21, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDMISC, 0x000ad0d0)
|
||||
MXC_DCD_ITEM(22, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCFG0, 0x333574aa)
|
||||
MXC_DCD_ITEM(23, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCFG1, 0x333574aa)
|
||||
/* Init DRAM on CS0 */
|
||||
MXC_DCD_ITEM(24, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x04008008)
|
||||
MXC_DCD_ITEM(25, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0000801a)
|
||||
MXC_DCD_ITEM(26, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0000801b)
|
||||
MXC_DCD_ITEM(27, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00448019)
|
||||
MXC_DCD_ITEM(28, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x07328018)
|
||||
MXC_DCD_ITEM(29, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x04008008)
|
||||
MXC_DCD_ITEM(30, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008010)
|
||||
MXC_DCD_ITEM(31, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008010)
|
||||
MXC_DCD_ITEM(32, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x06328018)
|
||||
MXC_DCD_ITEM(33, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x03808019)
|
||||
MXC_DCD_ITEM(34, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00408019)
|
||||
MXC_DCD_ITEM(35, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008000)
|
||||
/* Init DRAM on CS1 */
|
||||
MXC_DCD_ITEM(36, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0400800c)
|
||||
MXC_DCD_ITEM(37, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0000801e)
|
||||
MXC_DCD_ITEM(39, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0000801f)
|
||||
MXC_DCD_ITEM(40, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0000801d)
|
||||
MXC_DCD_ITEM(41, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0732801c)
|
||||
MXC_DCD_ITEM(42, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0400800c)
|
||||
MXC_DCD_ITEM(43, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008014)
|
||||
MXC_DCD_ITEM(44, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008014)
|
||||
MXC_DCD_ITEM(45, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0632801c)
|
||||
MXC_DCD_ITEM(46, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0380801d)
|
||||
MXC_DCD_ITEM(47, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x0040801d)
|
||||
MXC_DCD_ITEM(48, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00008004)
|
||||
|
||||
MXC_DCD_ITEM(49, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCTL0, 0xb2a20000)
|
||||
MXC_DCD_ITEM(50, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCTL1, 0xb2a20000)
|
||||
MXC_DCD_ITEM(51, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDMISC, 0x000ad6d0)
|
||||
MXC_DCD_ITEM(52, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCDLYGD, 0x90000000)
|
||||
MXC_DCD_ITEM(53, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00000000)
|
||||
|
||||
/* Delay settings */
|
||||
MXC_DCD_ITEM(57, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCDLY1, 0x00048000)
|
||||
MXC_DCD_ITEM(58, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCDLY2, 0x000e8000)
|
||||
MXC_DCD_ITEM(59, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCDLY3, 0x00ff8000)
|
||||
MXC_DCD_ITEM(60, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCDLY4, 0x00fa8000)
|
||||
MXC_DCD_ITEM(61, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCDLY5, 0x00ed8000)
|
||||
#endif
|
||||
dcd_data_end:
|
||||
image_len: .word 0x40000
|
||||
//image_len: .word _end - _start
|
||||
#endif
|
||||
348
board/freescale/mx51_3stack/lowlevel_init.S
Normal file
348
board/freescale/mx51_3stack/lowlevel_init.S
Normal file
@ -0,0 +1,348 @@
|
||||
/*
|
||||
* Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
|
||||
*
|
||||
* (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include <asm/arch/mx51.h>
|
||||
#include "board-mx51_3stack.h"
|
||||
|
||||
/*
|
||||
* return soc version
|
||||
* 0x10: TO1
|
||||
* 0x20: TO2
|
||||
* 0x30: TO3
|
||||
*/
|
||||
.macro check_soc_version ret, tmp
|
||||
.endm
|
||||
|
||||
/*
|
||||
* L2CC Cache setup/invalidation/disable
|
||||
*/
|
||||
.macro init_l2cc
|
||||
/* explicitly disable L2 cache */
|
||||
mrc 15, 0, r0, c1, c0, 1
|
||||
bic r0, r0, #0x2
|
||||
mcr 15, 0, r0, c1, c0, 1
|
||||
|
||||
/* reconfigure L2 cache aux control reg */
|
||||
mov r0, #0xC0 /* tag RAM */
|
||||
add r0, r0, #0x4 /* data RAM */
|
||||
orr r0, r0, #(1 << 24) /* disable write allocate delay */
|
||||
orr r0, r0, #(1 << 23) /* disable write allocate combine */
|
||||
orr r0, r0, #(1 << 22) /* disable write allocate */
|
||||
|
||||
ldr r1, =0x00000000
|
||||
ldr r3, [r1, #ROM_SI_REV]
|
||||
cmp r3, #0x10
|
||||
orrls r0, r0, #(1 << 25) /* disable write combine for TO 2 and lower revs */
|
||||
|
||||
mcr 15, 1, r0, c9, c0, 2
|
||||
.endm /* init_l2cc */
|
||||
|
||||
/* AIPS setup - Only setup MPROTx registers.
|
||||
* The PACR default values are good.*/
|
||||
.macro init_aips
|
||||
/*
|
||||
* Set all MPROTx to be non-bufferable, trusted for R/W,
|
||||
* not forced to user-mode.
|
||||
*/
|
||||
ldr r0, =AIPS1_BASE_ADDR
|
||||
ldr r1, =0x77777777
|
||||
str r1, [r0, #0x0]
|
||||
str r1, [r0, #0x4]
|
||||
ldr r0, =AIPS2_BASE_ADDR
|
||||
str r1, [r0, #0x0]
|
||||
str r1, [r0, #0x4]
|
||||
/*
|
||||
* Clear the on and off peripheral modules Supervisor Protect bit
|
||||
* for SDMA to access them. Did not change the AIPS control registers
|
||||
* (offset 0x20) access type
|
||||
*/
|
||||
.endm /* init_aips */
|
||||
|
||||
/* MAX (Multi-Layer AHB Crossbar Switch) setup */
|
||||
.macro init_max
|
||||
.endm /* init_max */
|
||||
|
||||
/* M4IF setup */
|
||||
.macro init_m4if
|
||||
/* VPU and IPU given higher priority (0x4)
|
||||
* IPU accesses with ID=0x1 given highest priority (=0xA)
|
||||
*/
|
||||
ldr r0, =M4IF_BASE_ADDR
|
||||
|
||||
ldr r1, =0x00000203
|
||||
str r1, [r0, #0x40]
|
||||
|
||||
ldr r1, =0x0
|
||||
str r1, [r0, #0x44]
|
||||
|
||||
ldr r1, =0x00120125
|
||||
str r1, [r0, #0x9C]
|
||||
|
||||
ldr r1, =0x001901A3
|
||||
str r1, [r0, #0x48]
|
||||
str r1, [r0, #0x40]
|
||||
.endm /* init_m4if */
|
||||
|
||||
/* To support 133MHz DDR */
|
||||
.macro init_drive_strength
|
||||
.endm /* init_drive_strength */
|
||||
|
||||
/* CPLD on CS5 setup */
|
||||
.macro init_debug_board
|
||||
.endm /* init_debug_board */
|
||||
|
||||
.macro setup_pll pll, freq
|
||||
ldr r2, =\pll
|
||||
ldr r1, =0x00001232
|
||||
str r1, [r2, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */
|
||||
mov r1, #0x2
|
||||
str r1, [r2, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */
|
||||
|
||||
str r3, [r2, #PLL_DP_OP]
|
||||
str r3, [r2, #PLL_DP_HFS_OP]
|
||||
|
||||
str r4, [r2, #PLL_DP_MFD]
|
||||
str r4, [r2, #PLL_DP_HFS_MFD]
|
||||
|
||||
str r5, [r2, #PLL_DP_MFN]
|
||||
str r5, [r2, #PLL_DP_HFS_MFN]
|
||||
|
||||
ldr r1, =0x00001232
|
||||
str r1, [r2, #PLL_DP_CTL]
|
||||
1: ldr r1, [r2, #PLL_DP_CTL]
|
||||
ands r1, r1, #0x1
|
||||
beq 1b
|
||||
.endm
|
||||
|
||||
.macro init_clock
|
||||
ldr r0, =CCM_BASE_ADDR
|
||||
|
||||
/* Gate of clocks to the peripherals first */
|
||||
ldr r1, =0x3FFFFFFF
|
||||
str r1, [r0, #CLKCTL_CCGR0]
|
||||
ldr r1, =0x0
|
||||
str r1, [r0, #CLKCTL_CCGR1]
|
||||
str r1, [r0, #CLKCTL_CCGR2]
|
||||
str r1, [r0, #CLKCTL_CCGR3]
|
||||
|
||||
ldr r1, =0x00030000
|
||||
str r1, [r0, #CLKCTL_CCGR4]
|
||||
ldr r1, =0x00FFF030
|
||||
str r1, [r0, #CLKCTL_CCGR5]
|
||||
ldr r1, =0x00000300
|
||||
str r1, [r0, #CLKCTL_CCGR6]
|
||||
|
||||
mov r1, #0x00060000
|
||||
str r1, [r0, #CLKCTL_CCDR]
|
||||
|
||||
/* Switch ARM to step clock */
|
||||
mov r1, #0x4
|
||||
str r1, [r0, #CLKCTL_CCSR]
|
||||
|
||||
mov r3, #DP_OP_800
|
||||
mov r4, #DP_MFD_800
|
||||
mov r5, #DP_MFN_800
|
||||
setup_pll PLL1_BASE_ADDR
|
||||
mov r3, #DP_OP_665
|
||||
mov r4, #DP_MFD_665
|
||||
mov r5, #DP_MFN_665
|
||||
setup_pll PLL3_BASE_ADDR
|
||||
|
||||
/* Switch peripheral to PLL 3 */
|
||||
ldr r0, =CCM_BASE_ADDR
|
||||
ldr r1, =0x000010C0
|
||||
str r1, [r0, #CLKCTL_CBCMR]
|
||||
ldr r1, =0x13239145
|
||||
str r1, [r0, #CLKCTL_CBCDR]
|
||||
|
||||
mov r3, #DP_OP_665
|
||||
mov r4, #DP_MFD_665
|
||||
mov r5, #DP_MFN_665
|
||||
setup_pll PLL2_BASE_ADDR
|
||||
|
||||
/* Switch peripheral to PLL2 */
|
||||
ldr r0, =CCM_BASE_ADDR
|
||||
ldr r1, =0x19239145
|
||||
str r1, [r0, #CLKCTL_CBCDR]
|
||||
ldr r1, =0x000020C0
|
||||
str r1, [r0, #CLKCTL_CBCMR]
|
||||
|
||||
mov r3, #DP_OP_216
|
||||
mov r4, #DP_MFD_216
|
||||
mov r5, #DP_MFN_216
|
||||
setup_pll PLL3_BASE_ADDR
|
||||
|
||||
/* Set the platform clock dividers */
|
||||
ldr r2, =ARM_BASE_ADDR
|
||||
ldr r1, =0x00000725
|
||||
str r1, [r2, #0x14]
|
||||
|
||||
ldr r0, =CCM_BASE_ADDR
|
||||
/* Run TO 3.0 at Full speed, for other TO's wait till we increase VDDGP */
|
||||
ldr r1, =0x00000000
|
||||
ldr r3, [r1, #ROM_SI_REV]
|
||||
cmp r3, #0x10
|
||||
movls r1, #0x1
|
||||
movhi r1, #0
|
||||
str r1, [r0, #CLKCTL_CACRR]
|
||||
|
||||
/* Switch ARM back to PLL 1 */
|
||||
mov r1, #0
|
||||
str r1, [r0, #CLKCTL_CCSR]
|
||||
|
||||
/* setup the rest */
|
||||
/* Use lp_apm (24MHz) source for perclk */
|
||||
ldr r1, =0x000020C2
|
||||
str r1, [r0, #CLKCTL_CBCMR]
|
||||
/* ddr clock from PLL 1, all perclk dividers are 1 since using 24MHz */
|
||||
#ifdef CONFIG_IMX51_MDDR
|
||||
ldr r1, =0x61E35100
|
||||
#else
|
||||
ldr r1, =0x59E35100
|
||||
#endif
|
||||
str r1, [r0, #CLKCTL_CBCDR]
|
||||
|
||||
/* Restore the default values in the Gate registers */
|
||||
ldr r1, =0xFFFFFFFF
|
||||
str r1, [r0, #CLKCTL_CCGR0]
|
||||
str r1, [r0, #CLKCTL_CCGR1]
|
||||
str r1, [r0, #CLKCTL_CCGR2]
|
||||
str r1, [r0, #CLKCTL_CCGR3]
|
||||
str r1, [r0, #CLKCTL_CCGR4]
|
||||
str r1, [r0, #CLKCTL_CCGR5]
|
||||
str r1, [r0, #CLKCTL_CCGR6]
|
||||
|
||||
/* Use PLL 2 for UART's, get 66.5MHz from it */
|
||||
ldr r1, =0xA5A2A020
|
||||
str r1, [r0, #CLKCTL_CSCMR1]
|
||||
ldr r1, =0x00C30321
|
||||
str r1, [r0, #CLKCTL_CSCDR1]
|
||||
|
||||
/* make sure divider effective */
|
||||
1: ldr r1, [r0, #CLKCTL_CDHIPR]
|
||||
cmp r1, #0
|
||||
bne 1b
|
||||
|
||||
mov r1, #0x0
|
||||
str r1, [r0, #CLKCTL_CCDR]
|
||||
|
||||
/* for cko - for ARM div by 8 */
|
||||
mov r1, #0x000A0000
|
||||
add r1, r1, #0x00000F0
|
||||
str r1, [r0, #CLKCTL_CCOSR]
|
||||
.endm
|
||||
|
||||
.macro setup_wdog
|
||||
ldr r0, =WDOG1_BASE_ADDR
|
||||
mov r1, #0x30
|
||||
strh r1, [r0]
|
||||
.endm
|
||||
|
||||
.macro setup_sdram
|
||||
ldr r0, =ESDCTL_BASE_ADDR
|
||||
/* Set CSD0 */
|
||||
mov r1, #0x80000000
|
||||
str r1, [r0, #ESDCTL_ESDCTL0]
|
||||
/* Precharge command */
|
||||
ldr r1, DDR_PERCHARGE_CMD
|
||||
str r1, [r0, #ESDCTL_ESDSCR]
|
||||
/* 2 refresh commands */
|
||||
ldr r1, DDR_REFRESH_CMD
|
||||
str r1, [r0, #ESDCTL_ESDSCR]
|
||||
str r1, [r0, #ESDCTL_ESDSCR]
|
||||
/* LMR with CAS=3 and BL=3 */
|
||||
ldr r1, DDR_LMR1_W
|
||||
str r1, [r0, #ESDCTL_ESDSCR]
|
||||
/* 13 ROW, 10 COL, 32Bit, SREF=4 Micron Model */
|
||||
ldr r1, DDR_LMR_CMD
|
||||
str r1, [r0, #ESDCTL_ESDCTL0]
|
||||
/* Timing parameters */
|
||||
ldr r1, DDR_TIMING_W
|
||||
str r1, [r0, #ESDCTL_ESDCFG0]
|
||||
/* MDDR enable, RLAT=2 */
|
||||
ldr r1, DDR_MISC_W
|
||||
str r1, [r0, #ESDCTL_ESDMISC]
|
||||
/* Normal mode */
|
||||
mov r1, #0x00000000
|
||||
str r1, [r0, #ESDCTL_ESDSCR]
|
||||
1:
|
||||
.endm /* setup_sdram */
|
||||
|
||||
.section ".text.init", "x"
|
||||
|
||||
.globl lowlevel_init
|
||||
lowlevel_init:
|
||||
/* Platform CHIP level init*/
|
||||
ldr r0, =GPC_BASE_ADDR
|
||||
ldr r1, =0x1FC00000
|
||||
str r1, [r0, #4]
|
||||
|
||||
#ifdef ENABLE_IMPRECISE_ABORT
|
||||
mrs r1, spsr /* save old spsr */
|
||||
mrs r0, cpsr /* read out the cpsr */
|
||||
bic r0, r0, #0x100 /* clear the A bit */
|
||||
msr spsr, r0 /* update spsr */
|
||||
add lr, pc, #0x8 /* update lr */
|
||||
movs pc, lr /* update cpsr */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
msr spsr, r1 /* restore old spsr */
|
||||
#endif
|
||||
|
||||
init_l2cc
|
||||
|
||||
init_aips
|
||||
|
||||
setup_wdog
|
||||
|
||||
init_max
|
||||
|
||||
init_m4if
|
||||
|
||||
init_drive_strength
|
||||
|
||||
cmp pc, #PHYS_SDRAM_1
|
||||
blo do_sdram_setup
|
||||
cmp pc, #(PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)
|
||||
blo init_clock_start
|
||||
|
||||
do_sdram_setup:
|
||||
setup_sdram
|
||||
|
||||
init_clock_start:
|
||||
init_clock
|
||||
init_debug_board
|
||||
/*init_sdram*/
|
||||
|
||||
/* return from mxc_nand_load */
|
||||
/* r12 saved upper lr*/
|
||||
b mxc_nand_load
|
||||
|
||||
/* Board level setting value */
|
||||
DDR_PERCHARGE_CMD: .word 0x04008008
|
||||
DDR_REFRESH_CMD: .word 0x00008010
|
||||
DDR_LMR1_W: .word 0x00338018
|
||||
DDR_LMR_CMD: .word 0xB2220000
|
||||
DDR_TIMING_W: .word 0xB02567A9
|
||||
DDR_MISC_W: .word 0x000A0104
|
||||
590
board/freescale/mx51_3stack/mx51_3stack.c
Normal file
590
board/freescale/mx51_3stack/mx51_3stack.c
Normal file
@ -0,0 +1,590 @@
|
||||
/*
|
||||
* Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
|
||||
*
|
||||
* (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/arch/mx51.h>
|
||||
#include <asm/arch/mx51_pins.h>
|
||||
#include <asm/arch/iomux.h>
|
||||
#ifdef CONFIG_I2C_MXC
|
||||
#include <i2c.h>
|
||||
#endif
|
||||
#include <mxc_keyb.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include "board-mx51_3stack.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static u32 system_rev;
|
||||
u32 mx51_io_base_addr;
|
||||
volatile u32 *esdhc_base_pointer;
|
||||
|
||||
u32 get_board_rev(void)
|
||||
{
|
||||
return system_rev;
|
||||
}
|
||||
|
||||
static inline void setup_soc_rev(void)
|
||||
{
|
||||
int reg;
|
||||
reg = __REG(ROM_SI_REV);
|
||||
switch (reg) {
|
||||
case 0x02:
|
||||
system_rev = 0x51000 | CHIP_REV_1_1;
|
||||
break;
|
||||
case 0x10:
|
||||
system_rev = 0x51000 | CHIP_REV_2_0;
|
||||
break;
|
||||
default:
|
||||
system_rev = 0x51000 | CHIP_REV_1_0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void set_board_rev(int rev)
|
||||
{
|
||||
system_rev |= (rev & 0xF) << 8;
|
||||
}
|
||||
|
||||
inline int is_soc_rev(int rev)
|
||||
{
|
||||
return (system_rev & 0xFF) - rev;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
|
||||
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setup_uart(void)
|
||||
{
|
||||
unsigned int pad = PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE |
|
||||
PAD_CTL_PUE_PULL | PAD_CTL_DRV_HIGH;
|
||||
mxc_request_iomux(MX51_PIN_UART1_RXD, IOMUX_CONFIG_ALT0);
|
||||
mxc_iomux_set_pad(MX51_PIN_UART1_RXD, pad | PAD_CTL_SRE_FAST);
|
||||
mxc_request_iomux(MX51_PIN_UART1_TXD, IOMUX_CONFIG_ALT0);
|
||||
mxc_iomux_set_pad(MX51_PIN_UART1_TXD, pad | PAD_CTL_SRE_FAST);
|
||||
mxc_request_iomux(MX51_PIN_UART1_RTS, IOMUX_CONFIG_ALT0);
|
||||
mxc_iomux_set_pad(MX51_PIN_UART1_RTS, pad);
|
||||
mxc_request_iomux(MX51_PIN_UART1_CTS, IOMUX_CONFIG_ALT0);
|
||||
mxc_iomux_set_pad(MX51_PIN_UART1_CTS, pad);
|
||||
}
|
||||
|
||||
void setup_nfc(void)
|
||||
{
|
||||
/* Enable NFC IOMUX */
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS0, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS1, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS2, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS3, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS4, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS5, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS6, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_NANDF_CS7, IOMUX_CONFIG_ALT0);
|
||||
}
|
||||
|
||||
static void setup_expio(void)
|
||||
{
|
||||
u32 reg;
|
||||
/* CS5 setup */
|
||||
mxc_request_iomux(MX51_PIN_EIM_CS5, IOMUX_CONFIG_ALT0);
|
||||
writel(0x00410089, WEIM_BASE_ADDR + 0x78 + CSGCR1);
|
||||
writel(0x00000002, WEIM_BASE_ADDR + 0x78 + CSGCR2);
|
||||
/* RWSC=50, RADVA=2, RADVN=6, OEA=0, OEN=0, RCSA=0, RCSN=0 */
|
||||
writel(0x32260000, WEIM_BASE_ADDR + 0x78 + CSRCR1);
|
||||
/* APR = 0 */
|
||||
writel(0x00000000, WEIM_BASE_ADDR + 0x78 + CSRCR2);
|
||||
/* WAL=0, WBED=1, WWSC=50, WADVA=2, WADVN=6, WEA=0, WEN=0,
|
||||
* WCSA=0, WCSN=0
|
||||
*/
|
||||
writel(0x72080F00, WEIM_BASE_ADDR + 0x78 + CSWCR1);
|
||||
if ((readw(CS5_BASE_ADDR + PBC_ID_AAAA) == 0xAAAA) &&
|
||||
(readw(CS5_BASE_ADDR + PBC_ID_5555) == 0x5555)) {
|
||||
if (is_soc_rev(CHIP_REV_2_0) < 0) {
|
||||
reg = readl(CCM_BASE_ADDR + CLKCTL_CBCDR);
|
||||
reg = (reg & (~0x70000)) | 0x30000;
|
||||
writel(reg, CCM_BASE_ADDR + CLKCTL_CBCDR);
|
||||
/* make sure divider effective */
|
||||
while (readl(CCM_BASE_ADDR + CLKCTL_CDHIPR) != 0)
|
||||
;
|
||||
writel(0x0, CCM_BASE_ADDR + CLKCTL_CCDR);
|
||||
}
|
||||
mx51_io_base_addr = CS5_BASE_ADDR;
|
||||
} else {
|
||||
/* CS1 */
|
||||
writel(0x00410089, WEIM_BASE_ADDR + 0x18 + CSGCR1);
|
||||
writel(0x00000002, WEIM_BASE_ADDR + 0x18 + CSGCR2);
|
||||
/* RWSC=50, RADVA=2, RADVN=6, OEA=0, OEN=0, RCSA=0, RCSN=0 */
|
||||
writel(0x32260000, WEIM_BASE_ADDR + 0x18 + CSRCR1);
|
||||
/* APR=0 */
|
||||
writel(0x00000000, WEIM_BASE_ADDR + 0x18 + CSRCR2);
|
||||
/* WAL=0, WBED=1, WWSC=50, WADVA=2, WADVN=6, WEA=0,
|
||||
* WEN=0, WCSA=0, WCSN=0
|
||||
*/
|
||||
writel(0x72080F00, WEIM_BASE_ADDR + 0x18 + CSWCR1);
|
||||
mx51_io_base_addr = CS1_BASE_ADDR;
|
||||
}
|
||||
|
||||
/* Reset interrupt status reg */
|
||||
writew(0x1F, mx51_io_base_addr + PBC_INT_REST);
|
||||
writew(0x00, mx51_io_base_addr + PBC_INT_REST);
|
||||
writew(0xFFFF, mx51_io_base_addr + PBC_INT_MASK);
|
||||
|
||||
/* Reset the XUART and Ethernet controllers */
|
||||
reg = readw(mx51_io_base_addr + PBC_SW_RESET);
|
||||
reg |= 0x9;
|
||||
writew(reg, mx51_io_base_addr + PBC_SW_RESET);
|
||||
reg &= ~0x9;
|
||||
writew(reg, mx51_io_base_addr + PBC_SW_RESET);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_I2C_MXC
|
||||
static void setup_i2c(unsigned int module_base)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
switch (module_base) {
|
||||
case I2C1_BASE_ADDR:
|
||||
reg = IOMUXC_BASE_ADDR + 0x210; /* i2c SDA */
|
||||
writel(0x11, reg);
|
||||
reg = IOMUXC_BASE_ADDR + 0x600;
|
||||
writel(0x1ad, reg);
|
||||
reg = IOMUXC_BASE_ADDR + 0x9B4;
|
||||
writel(0x1, reg);
|
||||
|
||||
reg = IOMUXC_BASE_ADDR + 0x224; /* i2c SCL */
|
||||
writel(0x11, reg);
|
||||
reg = IOMUXC_BASE_ADDR + 0x614;
|
||||
writel(0x1ad, reg);
|
||||
reg = IOMUXC_BASE_ADDR + 0x9B0;
|
||||
writel(0x1, reg);
|
||||
break;
|
||||
case I2C2_BASE_ADDR:
|
||||
/* Workaround for Atlas Lite */
|
||||
writel(0x0, IOMUXC_BASE_ADDR + 0x3CC); /* i2c SCL */
|
||||
writel(0x0, IOMUXC_BASE_ADDR + 0x3D0); /* i2c SDA */
|
||||
reg = readl(GPIO1_BASE_ADDR + 0x0);
|
||||
reg |= 0xC; /* write a 1 on the SCL and SDA lines */
|
||||
writel(reg, GPIO1_BASE_ADDR + 0x0);
|
||||
reg = readl(GPIO1_BASE_ADDR + 0x4);
|
||||
reg |= 0xC; /* configure GPIO lines as output */
|
||||
writel(reg, GPIO1_BASE_ADDR + 0x4);
|
||||
reg = readl(GPIO1_BASE_ADDR + 0x0);
|
||||
reg &= ~0x4 ; /* set SCL low for a few milliseconds */
|
||||
writel(reg, GPIO1_BASE_ADDR + 0x0);
|
||||
udelay(20000);
|
||||
reg |= 0x4;
|
||||
writel(reg, GPIO1_BASE_ADDR + 0x0);
|
||||
udelay(10);
|
||||
reg = readl(GPIO1_BASE_ADDR + 0x4);
|
||||
reg &= ~0xC; /* configure GPIO lines back as input */
|
||||
writel(reg, GPIO1_BASE_ADDR + 0x4);
|
||||
|
||||
writel(0x12, IOMUXC_BASE_ADDR + 0x3CC); /* i2c SCL */
|
||||
writel(0x3, IOMUXC_BASE_ADDR + 0x9B8);
|
||||
writel(0x1ed, IOMUXC_BASE_ADDR + 0x7D4);
|
||||
|
||||
writel(0x12, IOMUXC_BASE_ADDR + 0x3D0); /* i2c SDA */
|
||||
writel(0x3, IOMUXC_BASE_ADDR + 0x9BC);
|
||||
writel(0x1ed, IOMUXC_BASE_ADDR + 0x7D8);
|
||||
break;
|
||||
default:
|
||||
printf("Invalid I2C base: 0x%x\n", module_base);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define REV_ATLAS_LITE_1_0 0x8
|
||||
#define REV_ATLAS_LITE_1_1 0x9
|
||||
#define REV_ATLAS_LITE_2_0 0x10
|
||||
#define REV_ATLAS_LITE_2_1 0x11
|
||||
|
||||
void setup_core_voltages(void)
|
||||
{
|
||||
unsigned char buf[4] = { 0 };
|
||||
|
||||
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
|
||||
|
||||
if (is_soc_rev(CHIP_REV_2_0) <= 0) {
|
||||
/* Set core voltage to 1.1V */
|
||||
if (i2c_read(0x8, 24, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: read PMIC@0x08:0x18 fail\n");
|
||||
return;
|
||||
}
|
||||
buf[2] = (buf[2] & (~0x1F)) | 0x14;
|
||||
if (i2c_write(0x8, 24, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: write PMIC@0x08:0x18 fail\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Setup VCC (SW2) to 1.25 */
|
||||
if (i2c_read(0x8, 25, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: read PMIC@0x08:0x19 fail\n");
|
||||
return;
|
||||
}
|
||||
buf[2] = (buf[2] & (~0x1F)) | 0x1A;
|
||||
if (i2c_write(0x8, 25, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: write PMIC@0x08:0x19 fail\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Setup 1V2_DIG1 (SW3) to 1.25 */
|
||||
if (i2c_read(0x8, 26, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: read PMIC@0x08:0x1A fail\n");
|
||||
return;
|
||||
}
|
||||
buf[2] = (buf[2] & (~0x1F)) | 0x1A;
|
||||
if (i2c_write(0x8, 26, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: write PMIC@0x08:0x1A fail\n");
|
||||
return;
|
||||
}
|
||||
|
||||
udelay(50);
|
||||
|
||||
/* Raise the core frequency to 800MHz */
|
||||
writel(0x0, CCM_BASE_ADDR + CLKCTL_CACRR);
|
||||
} else {
|
||||
/* TO 3.0 */
|
||||
/* Setup VCC (SW2) to 1.225 */
|
||||
if (i2c_read(0x8, 25, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: read PMIC@0x08:0x19 fail\n");
|
||||
return;
|
||||
}
|
||||
buf[2] = (buf[2] & (~0x1F)) | 0x19;
|
||||
if (i2c_write(0x8, 25, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: write PMIC@0x08:0x19 fail\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Setup 1V2_DIG1 (SW3) to 1.2 */
|
||||
if (i2c_read(0x8, 26, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: read PMIC@0x08:0x1A fail\n");
|
||||
return;
|
||||
}
|
||||
buf[2] = (buf[2] & (~0x1F)) | 0x18;
|
||||
if (i2c_write(0x8, 26, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: write PMIC@0x08:0x1A fail\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (i2c_read(0x8, 7, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: read PMIC@0x08:0x07 fail\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (((buf[2] & 0x1F) < REV_ATLAS_LITE_2_0) || (((buf[1] >> 1) & 0x3) == 0)) {
|
||||
/* Set switchers in PWM mode for Atlas 2.0 and lower */
|
||||
/* Setup the switcher mode for SW1 & SW2*/
|
||||
if (i2c_read(0x8, 28, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: read PMIC@0x08:0x1C fail\n");
|
||||
return;
|
||||
}
|
||||
buf[2] = (buf[2] & (~0xF)) | 0x5;
|
||||
buf[1] = (buf[1] & (~0x3C)) | 0x14;
|
||||
if (i2c_write(0x8, 28, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: write PMIC@0x08:0x1C fail\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Setup the switcher mode for SW3 & SW4*/
|
||||
if (i2c_read(0x8, 29, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: read PMIC@0x08:0x1D fail\n");
|
||||
return;
|
||||
}
|
||||
buf[2] = (buf[2] & (~0xF)) | 0x5;
|
||||
buf[1] = (buf[1] & (~0xF)) | 0x5;
|
||||
if (i2c_write(0x8, 29, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: write PMIC@0x08:0x1D fail\n");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* Set switchers in Auto in NORMAL mode & STANDBY mode for Atlas 2.0a */
|
||||
/* Setup the switcher mode for SW1 & SW2*/
|
||||
if (i2c_read(0x8, 28, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: read PMIC@0x08:0x1C fail\n");
|
||||
return;
|
||||
}
|
||||
buf[2] = (buf[2] & (~0xF)) | 0x8;
|
||||
buf[1] = (buf[1] & (~0x3C)) | 0x20;
|
||||
if (i2c_write(0x8, 28, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: write PMIC@0x08:0x1C fail\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Setup the switcher mode for SW3 & SW4*/
|
||||
if (i2c_read(0x8, 29, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: read PMIC@0x08:0x1D fail\n");
|
||||
return;
|
||||
}
|
||||
buf[2] = (buf[2] & (~0xF)) | 0x8;
|
||||
buf[1] = (buf[1] & (~0xF)) | 0x8;
|
||||
if (i2c_write(0x8, 29, 1, buf, 3)) {
|
||||
puts("setup_core_voltages: write PMIC@0x08:0x1D fail\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
setup_soc_rev();
|
||||
|
||||
gd->bd->bi_arch_number = MACH_TYPE_MX51_3DS; /* board id for linux */
|
||||
/* address of boot parameters */
|
||||
gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
|
||||
|
||||
setup_uart();
|
||||
setup_nfc();
|
||||
setup_expio();
|
||||
#ifdef CONFIG_I2C_MXC
|
||||
setup_i2c(I2C2_BASE_ADDR);
|
||||
setup_core_voltages();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef BOARD_LATE_INIT
|
||||
int board_late_init(void)
|
||||
{
|
||||
#if defined(CONFIG_FSL_ANDROID) && defined(CONFIG_MXC_KPD)
|
||||
struct kpp_key_info key_info = {0, 0};
|
||||
int switch_delay = CONFIG_ANDROID_BOOTMOD_DELAY;
|
||||
int state = 0, boot_mode_switch = 0;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FSL_ANDROID) && defined(CONFIG_MXC_KPD)
|
||||
mxc_kpp_init();
|
||||
|
||||
puts("Press home + power to enter recovery mode ...\n");
|
||||
|
||||
while ((switch_delay > 0) && (!boot_mode_switch)) {
|
||||
int i;
|
||||
|
||||
--switch_delay;
|
||||
/* delay 100 * 10ms */
|
||||
for (i = 0; !boot_mode_switch && i < 100; ++i) {
|
||||
/* A state machine to scan home + power key */
|
||||
/* Check for home + power */
|
||||
if (mxc_kpp_getc(&key_info)) {
|
||||
switch (state) {
|
||||
case 0:
|
||||
/* First press */
|
||||
if (TEST_HOME_KEY_DEPRESS(key_info.val, key_info.evt)) {
|
||||
/* Press Home */
|
||||
state = 1;
|
||||
} else if (TEST_POWER_KEY_DEPRESS(key_info.val, key_info.evt)) {
|
||||
state = 2;
|
||||
} else {
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* Home is already pressed, try to detect Power */
|
||||
if (TEST_POWER_KEY_DEPRESS(key_info.val,
|
||||
key_info.evt)) {
|
||||
boot_mode_switch = 1;
|
||||
} else {
|
||||
if (TEST_HOME_KEY_DEPRESS(key_info.val,
|
||||
key_info.evt))
|
||||
state = 2;
|
||||
else
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
/* Power is already pressed, try to detect Home */
|
||||
if (TEST_HOME_KEY_DEPRESS(key_info.val,
|
||||
key_info.evt)) {
|
||||
boot_mode_switch = 1;
|
||||
} else {
|
||||
if (TEST_POWER_KEY_DEPRESS(key_info.val,
|
||||
key_info.evt))
|
||||
state = 1;
|
||||
else
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (1 == boot_mode_switch) {
|
||||
printf("Boot mode switched to recovery mode!\n");
|
||||
/* Set env to recovery mode */
|
||||
setenv("bootargs_android", CONFIG_ANDROID_RECOVERY_BOOTARGS);
|
||||
setenv("bootcmd_android", CONFIG_ANDROID_RECOVERY_BOOTCMD);
|
||||
setenv("bootcmd", "run bootcmd_android");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 100; ++i)
|
||||
udelay(10000);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
printf("Board: MX51 3STACK ");
|
||||
|
||||
if (system_rev & CHIP_REV_2_0) {
|
||||
printf("2.0 [");
|
||||
} else if (system_rev & CHIP_REV_1_1) {
|
||||
printf("1.1 [");
|
||||
} else {
|
||||
printf("1.0 [");
|
||||
}
|
||||
|
||||
switch (__REG(SRC_BASE_ADDR + 0x8)) {
|
||||
case 0x0001:
|
||||
printf("POR");
|
||||
break;
|
||||
case 0x0009:
|
||||
printf("RST");
|
||||
break;
|
||||
case 0x0010:
|
||||
case 0x0011:
|
||||
printf("WDOG");
|
||||
break;
|
||||
default:
|
||||
printf("unknown");
|
||||
}
|
||||
printf("]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_MULTI
|
||||
int board_eth_init(bd_t *bis)
|
||||
{
|
||||
int rc = -ENODEV;
|
||||
#if defined(CONFIG_DRIVER_SMC911X)
|
||||
rc = smc911x_initialize(bis);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FSL_MMC
|
||||
|
||||
int sdhc_init(void)
|
||||
{
|
||||
u32 interface_esdhc = 0;
|
||||
s32 status = 0;
|
||||
|
||||
interface_esdhc = (readl(SRC_BASE_ADDR + 0x4) & (0x00180000)) >> 19;
|
||||
|
||||
switch (interface_esdhc) {
|
||||
case 0:
|
||||
|
||||
esdhc_base_pointer = (volatile u32 *)MMC_SDHC1_BASE_ADDR;
|
||||
|
||||
mxc_request_iomux(MX51_PIN_SD1_CMD,
|
||||
IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
|
||||
mxc_request_iomux(MX51_PIN_SD1_CLK,
|
||||
IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
|
||||
|
||||
mxc_request_iomux(MX51_PIN_SD1_DATA0,
|
||||
IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
|
||||
mxc_request_iomux(MX51_PIN_SD1_DATA1,
|
||||
IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
|
||||
mxc_request_iomux(MX51_PIN_SD1_DATA2,
|
||||
IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
|
||||
mxc_request_iomux(MX51_PIN_SD1_DATA3,
|
||||
IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD1_CMD,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
|
||||
PAD_CTL_HYS_ENABLE | PAD_CTL_47K_PU |
|
||||
PAD_CTL_PUE_PULL |
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD1_CLK,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
|
||||
PAD_CTL_HYS_NONE | PAD_CTL_47K_PU |
|
||||
PAD_CTL_PUE_PULL |
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD1_DATA0,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
|
||||
PAD_CTL_HYS_ENABLE | PAD_CTL_47K_PU |
|
||||
PAD_CTL_PUE_PULL |
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD1_DATA1,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
|
||||
PAD_CTL_HYS_ENABLE | PAD_CTL_47K_PU |
|
||||
PAD_CTL_PUE_PULL |
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD1_DATA2,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
|
||||
PAD_CTL_HYS_ENABLE | PAD_CTL_47K_PU |
|
||||
PAD_CTL_PUE_PULL |
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
|
||||
mxc_iomux_set_pad(MX51_PIN_SD1_DATA3,
|
||||
PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
|
||||
PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PD |
|
||||
PAD_CTL_PUE_PULL |
|
||||
PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
|
||||
break;
|
||||
case 1:
|
||||
status = 1;
|
||||
break;
|
||||
case 2:
|
||||
status = 1;
|
||||
break;
|
||||
case 3:
|
||||
status = 1;
|
||||
break;
|
||||
default:
|
||||
status = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return status = 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MXC_KPD)
|
||||
int setup_mxc_kpd()
|
||||
{
|
||||
mxc_request_iomux(MX51_PIN_KEY_COL0, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_COL1, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_COL2, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_COL3, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_COL4, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_COL5, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_ROW0, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_ROW1, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_ROW2, IOMUX_CONFIG_ALT0);
|
||||
mxc_request_iomux(MX51_PIN_KEY_ROW3, IOMUX_CONFIG_ALT0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
73
board/freescale/mx51_3stack/u-boot.lds
Normal file
73
board/freescale/mx51_3stack/u-boot.lds
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* January 2004 - Changed to support H4 device
|
||||
* Copyright (c) 2004 Texas Instruments
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
|
||||
*
|
||||
* (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
/* WARNING - the following is hand-optimized to fit within */
|
||||
/* the sector layout of our flash chips! XXX FIXME XXX */
|
||||
board/freescale/mx51_3stack/flash_header.o (.text.flasheader)
|
||||
cpu/arm_cortexa8/start.o
|
||||
board/freescale/mx51_3stack/libmx51_3stack.a (.text)
|
||||
lib_arm/libarm.a (.text)
|
||||
net/libnet.a (.text)
|
||||
drivers/mtd/libmtd.a (.text)
|
||||
drivers/mmc/libmmc.a (.text)
|
||||
|
||||
. = DEFINED(env_offset) ? env_offset : .;
|
||||
common/env_embedded.o(.text)
|
||||
|
||||
*(.text)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(.rodata) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : { *(.data) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.got : { *(.got) }
|
||||
|
||||
. = .;
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
.bss : { *(.bss) }
|
||||
_end = .;
|
||||
}
|
||||
52
board/stmp378x_dev/Makefile
Normal file
52
board/stmp378x_dev/Makefile
Normal file
@ -0,0 +1,52 @@
|
||||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@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$(BOARD).a
|
||||
|
||||
COBJS := stmp378x_dev.o
|
||||
SOBJS := lowlevel_init.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
SOBJS := $(addprefix $(obj),$(SOBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS) $(SOBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
rm -f $(LIB) core *.bak $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
5
board/stmp378x_dev/config.mk
Normal file
5
board/stmp378x_dev/config.mk
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# image should be loaded at 0x41008000
|
||||
#
|
||||
|
||||
TEXT_BASE = 0x41008000
|
||||
34
board/stmp378x_dev/lowlevel_init.S
Normal file
34
board/stmp378x_dev/lowlevel_init.S
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Board specific setup info
|
||||
*
|
||||
* (C) Copyright 2003, ARM Ltd.
|
||||
* Philippe Robin, <philippe.robin@arm.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., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <version.h>
|
||||
|
||||
/* Set up the platform, once the cpu has been initialized */
|
||||
.globl lowlevel_init
|
||||
lowlevel_init:
|
||||
|
||||
/* All SDRAM settings are done by sdram_prep */
|
||||
mov pc, lr
|
||||
158
board/stmp378x_dev/stmp378x_dev.c
Normal file
158
board/stmp378x_dev/stmp378x_dev.c
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
*
|
||||
* (c) 2008 Embedded Alley Solutions, Inc.
|
||||
*
|
||||
* (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <common.h>
|
||||
#include <asm/arch/stmp378x.h>
|
||||
#include <asm/arch/clkctrl.h>
|
||||
#include <asm/arch/pinmux.h>
|
||||
#include <asm/arch/spi.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define KHz 1000
|
||||
#define MHz (1000 * KHz)
|
||||
|
||||
static void set_pinmux(void)
|
||||
{
|
||||
|
||||
#if defined(CONFIG_SPI_SSP1)
|
||||
|
||||
/* Configure SSP1 pins for ENC28j60: 8maA */
|
||||
REG_CLR(PINCTRL_BASE + PINCTRL_MUXSEL(4), 0x00003fff);
|
||||
|
||||
REG_CLR(PINCTRL_BASE + PINCTRL_DRIVE(8), 0X03333333);
|
||||
REG_SET(PINCTRL_BASE + PINCTRL_DRIVE(8), 0x01111111);
|
||||
|
||||
REG_CLR(PINCTRL_BASE + PINCTRL_PULL(2), 0x0000003f);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPI_SSP2)
|
||||
|
||||
/* Configure SSP2 pins for ENC28j60: 8maA */
|
||||
REG_CLR(PINCTRL_BASE + PINCTRL_MUXSEL(0), 0x00000fc3);
|
||||
REG_SET(PINCTRL_BASE + PINCTRL_MUXSEL(0), 0x00000a82);
|
||||
|
||||
REG_CLR(PINCTRL_BASE + PINCTRL_MUXSEL(1), 0x00030300);
|
||||
REG_SET(PINCTRL_BASE + PINCTRL_MUXSEL(1), 0x00020200);
|
||||
|
||||
REG_CLR(PINCTRL_BASE + PINCTRL_DRIVE(0), 0X00333003);
|
||||
REG_SET(PINCTRL_BASE + PINCTRL_DRIVE(0), 0x00111001);
|
||||
|
||||
REG_CLR(PINCTRL_BASE + PINCTRL_DRIVE(2), 0x00030000);
|
||||
REG_SET(PINCTRL_BASE + PINCTRL_DRIVE(2), 0x00010000);
|
||||
|
||||
REG_CLR(PINCTRL_BASE + PINCTRL_DRIVE(3), 0x00000003);
|
||||
REG_SET(PINCTRL_BASE + PINCTRL_DRIVE(3), 0x00000001);
|
||||
|
||||
REG_CLR(PINCTRL_BASE + PINCTRL_PULL(0), 0x00100039);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#define IO_DIVIDER 18
|
||||
static void set_clocks(void)
|
||||
{
|
||||
u32 ssp_source_clk, ssp_clk;
|
||||
u32 ssp_div = 1;
|
||||
u32 val = 0;
|
||||
|
||||
/*
|
||||
* Configure 480Mhz IO clock
|
||||
*/
|
||||
|
||||
/* Ungate IO_CLK and set divider */
|
||||
REG_CLR(CLKCTRL_BASE + CLKCTRL_FRAC, FRAC_CLKGATEIO);
|
||||
REG_CLR(CLKCTRL_BASE + CLKCTRL_FRAC, 0x3f << FRAC_IOFRAC);
|
||||
REG_SET(CLKCTRL_BASE + CLKCTRL_FRAC, IO_DIVIDER << FRAC_IOFRAC);
|
||||
|
||||
/*
|
||||
* Set SSP CLK to desired value
|
||||
*/
|
||||
|
||||
/* Calculate SSP_CLK divider relatively to 480Mhz IO_CLK*/
|
||||
ssp_source_clk = 480 * MHz;
|
||||
ssp_clk = CONFIG_SSP_CLK;
|
||||
ssp_div = (ssp_source_clk + ssp_clk - 1) / ssp_clk;
|
||||
|
||||
/* Enable SSP clock */
|
||||
val = REG_RD(CLKCTRL_BASE + CLKCTRL_SSP);
|
||||
val &= ~SSP_CLKGATE;
|
||||
REG_WR(CLKCTRL_BASE + CLKCTRL_SSP, val);
|
||||
|
||||
/* Wait while clock is gated */
|
||||
while (REG_RD(CLKCTRL_BASE + CLKCTRL_SSP) & SSP_CLKGATE)
|
||||
;
|
||||
|
||||
/* Set SSP clock divider */
|
||||
val &= ~(0x1ff << SSP_DIV);
|
||||
val |= ssp_div << SSP_DIV;
|
||||
REG_WR(CLKCTRL_BASE + CLKCTRL_SSP, val);
|
||||
|
||||
/* Wait until new divider value is set */
|
||||
while (REG_RD(CLKCTRL_BASE + CLKCTRL_SSP) & SSP_BUSY)
|
||||
;
|
||||
|
||||
/* Set SSP clock source to IO_CLK */
|
||||
REG_SET(CLKCTRL_BASE + CLKCTRL_CLKSEQ, CLKSEQ_BYPASS_SSP);
|
||||
REG_CLR(CLKCTRL_BASE + CLKCTRL_CLKSEQ, CLKSEQ_BYPASS_SSP);
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
|
||||
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* arch number of Freescale STMP 378x development board */
|
||||
gd->bd->bi_arch_number = MACH_TYPE_STMP378X;
|
||||
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
|
||||
|
||||
set_clocks();
|
||||
|
||||
set_pinmux();
|
||||
|
||||
/* Configure SPI on SSP1 or SSP2 */
|
||||
spi_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int misc_init_r(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
printf("Board: STMP378x dev. \n");
|
||||
return 0;
|
||||
}
|
||||
51
board/stmp378x_dev/u-boot.lds
Normal file
51
board/stmp378x_dev/u-boot.lds
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* (C) Copyright 2002
|
||||
* Gary Jennejohn, DENX Software Engineering, <gj@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
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
cpu/arm926ejs/start.o (.text)
|
||||
*(.text)
|
||||
}
|
||||
.rodata : { *(.rodata) }
|
||||
. = ALIGN(4);
|
||||
.data : { *(.data) }
|
||||
. = ALIGN(4);
|
||||
.got : { *(.got) }
|
||||
|
||||
. = .;
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
.bss (NOLOAD) : { *(.bss) }
|
||||
_end = .;
|
||||
}
|
||||
@ -57,6 +57,7 @@ COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
|
||||
COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o
|
||||
COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o
|
||||
COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o
|
||||
COBJS-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o
|
||||
COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o
|
||||
|
||||
# command
|
||||
|
||||
@ -59,8 +59,9 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
!defined(CONFIG_ENV_IS_IN_NAND) && \
|
||||
!defined(CONFIG_ENV_IS_IN_ONENAND) && \
|
||||
!defined(CONFIG_ENV_IS_IN_SPI_FLASH) && \
|
||||
!defined(CONFIG_ENV_IS_IN_MMC) && \
|
||||
!defined(CONFIG_ENV_IS_NOWHERE)
|
||||
# error Define one of CONFIG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|ONENAND|SPI_FLASH|NOWHERE}
|
||||
# error Define one of CONFIG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|ONENAND|SPI_FLASH|MMC|NOWHERE}
|
||||
#endif
|
||||
|
||||
#define XMK_STR(x) #x
|
||||
@ -549,7 +550,8 @@ int getenv_r (char *name, char *buf, unsigned len)
|
||||
#if ((defined(CONFIG_ENV_IS_IN_NVRAM) || defined(CONFIG_ENV_IS_IN_EEPROM) \
|
||||
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_FLASH)) \
|
||||
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_NAND)) \
|
||||
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_ONENAND))) \
|
||||
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_ONENAND)) \
|
||||
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_MMC))) \
|
||||
&& !defined(CONFIG_ENV_IS_NOWHERE))
|
||||
int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
@ -605,7 +607,8 @@ U_BOOT_CMD(
|
||||
#if ((defined(CONFIG_ENV_IS_IN_NVRAM) || defined(CONFIG_ENV_IS_IN_EEPROM) \
|
||||
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_FLASH)) \
|
||||
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_NAND)) \
|
||||
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_ONENAND))) \
|
||||
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_ONENAND)) \
|
||||
|| (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_MMC))) \
|
||||
&& !defined(CONFIG_ENV_IS_NOWHERE))
|
||||
U_BOOT_CMD(
|
||||
saveenv, 1, 0, do_saveenv,
|
||||
|
||||
@ -140,7 +140,8 @@ uchar default_environment[] = {
|
||||
};
|
||||
|
||||
#if defined(CONFIG_ENV_IS_IN_NAND) /* Environment is in Nand Flash */ \
|
||||
|| defined(CONFIG_ENV_IS_IN_SPI_FLASH)
|
||||
|| defined(CONFIG_ENV_IS_IN_SPI_FLASH) \
|
||||
|| defined(CONFIG_ENV_IS_IN_MMC)
|
||||
int default_environment_size = sizeof(default_environment);
|
||||
#endif
|
||||
|
||||
|
||||
327
common/env_mmc.c
Normal file
327
common/env_mmc.c
Normal file
@ -0,0 +1,327 @@
|
||||
/*
|
||||
* (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
|
||||
* (C) Copyright 2000-2006
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Andreas Heppel <aheppel@sysgo.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
|
||||
*/
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#if defined(CONFIG_ENV_IS_IN_MMC) /* Environment is in MMC Flash */
|
||||
|
||||
#include <command.h>
|
||||
#include <environment.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <malloc.h>
|
||||
#include <mmc.h>
|
||||
|
||||
#if defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_MMC)
|
||||
#define CMD_SAVEENV
|
||||
#elif defined(CONFIG_ENV_OFFSET_REDUND)
|
||||
#error Cannot use CONFIG_ENV_OFFSET_REDUND without CONFIG_CMD_ENV & CONFIG_CMD_MMC
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ENV_SIZE_REDUND) && (CONFIG_ENV_SIZE_REDUND < CONFIG_ENV_SIZE)
|
||||
#error CONFIG_ENV_SIZE_REDUND should not be less then CONFIG_ENV_SIZE
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_INFERNO
|
||||
#error CONFIG_INFERNO not supported yet
|
||||
#endif
|
||||
|
||||
/* references to names in env_common.c */
|
||||
extern uchar default_environment[];
|
||||
extern int default_environment_size;
|
||||
|
||||
char *env_name_spec = "MMC";
|
||||
|
||||
#ifdef ENV_IS_EMBEDDED
|
||||
extern uchar environment[];
|
||||
env_t *env_ptr = (env_t *)(&environment[0]);
|
||||
#else /* ! ENV_IS_EMBEDDED */
|
||||
env_t *env_ptr;
|
||||
#endif /* ENV_IS_EMBEDDED */
|
||||
|
||||
/* local functions */
|
||||
#if !defined(ENV_IS_EMBEDDED)
|
||||
static void use_default(void);
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
uchar env_get_char_spec(int index)
|
||||
{
|
||||
return *((uchar *)(gd->env_addr + index));
|
||||
}
|
||||
|
||||
|
||||
/* this is called before nand_init()
|
||||
* so we can't read Nand to validate env data.
|
||||
* Mark it OK for now. env_relocate() in env_common.c
|
||||
* will call our relocate function which will does
|
||||
* the real validation.
|
||||
*
|
||||
* When using a NAND boot image (like sequoia_nand), the environment
|
||||
* can be embedded or attached to the U-Boot image in NAND flash. This way
|
||||
* the SPL loads not only the U-Boot image from NAND but also the
|
||||
* environment.
|
||||
*/
|
||||
int env_init(void)
|
||||
{
|
||||
#if defined(CONFIG_IS_EMBEDDED)
|
||||
size_t total;
|
||||
int crc1_ok = 0, crc2_ok = 0;
|
||||
env_t *tmp_env1, *tmp_env2;
|
||||
|
||||
total = CONFIG_ENV_SIZE;
|
||||
|
||||
tmp_env1 = env_ptr;
|
||||
tmp_env2 = (env_t *)((ulong)env_ptr + CONFIG_ENV_SIZE);
|
||||
|
||||
crc1_ok = (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc);
|
||||
crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc);
|
||||
|
||||
if (!crc1_ok && !crc2_ok)
|
||||
gd->env_valid = 0;
|
||||
else if (crc1_ok && !crc2_ok)
|
||||
gd->env_valid = 1;
|
||||
else if (!crc1_ok && crc2_ok)
|
||||
gd->env_valid = 2;
|
||||
else {
|
||||
/* both ok - check serial */
|
||||
if (tmp_env1->flags == 255 && tmp_env2->flags == 0)
|
||||
gd->env_valid = 2;
|
||||
else if (tmp_env2->flags == 255 && tmp_env1->flags == 0)
|
||||
gd->env_valid = 1;
|
||||
else if (tmp_env1->flags > tmp_env2->flags)
|
||||
gd->env_valid = 1;
|
||||
else if (tmp_env2->flags > tmp_env1->flags)
|
||||
gd->env_valid = 2;
|
||||
else /* flags are equal - almost impossible */
|
||||
gd->env_valid = 1;
|
||||
}
|
||||
|
||||
if (gd->env_valid == 1)
|
||||
env_ptr = tmp_env1;
|
||||
else if (gd->env_valid == 2)
|
||||
env_ptr = tmp_env2;
|
||||
|
||||
#else /* ENV_IS_EMBEDDED */
|
||||
gd->env_addr = (ulong)&default_environment[0];
|
||||
gd->env_valid = 1;
|
||||
|
||||
#endif /* ENV_IS_EMBEDDED */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CMD_SAVEENV
|
||||
/*
|
||||
* The legacy NAND code saved the environment in the first NAND device i.e.,
|
||||
* nand_dev_desc + 0. This is also the behaviour using the new NAND code.
|
||||
*/
|
||||
#ifdef CONFIG_ENV_OFFSET_REDUND
|
||||
int saveenv(void)
|
||||
{
|
||||
size_t total;
|
||||
int ret = 0;
|
||||
|
||||
env_ptr->flags++;
|
||||
total = CONFIG_ENV_SIZE;
|
||||
|
||||
if (gd->env_valid == 1) {
|
||||
puts("Writing to redundant MMC... ");
|
||||
ret = mmc_write((u_char *)env_ptr,
|
||||
CONFIG_ENV_OFFSET_REDUND, total);
|
||||
} else {
|
||||
puts("Writing to MMC... ");
|
||||
ret = mmc_write((u_char *)env_ptr,
|
||||
CONFIG_ENV_OFFSET, total);
|
||||
}
|
||||
if (ret || total != CONFIG_ENV_SIZE) {
|
||||
puts("failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
puts("done\n");
|
||||
gd->env_valid = (gd->env_valid == 2 ? 1 : 2);
|
||||
return ret;
|
||||
}
|
||||
#else /* ! CONFIG_ENV_OFFSET_REDUND */
|
||||
int saveenv(void)
|
||||
{
|
||||
size_t total;
|
||||
int ret = 0;
|
||||
|
||||
puts("Writing to MMC... ");
|
||||
total = CONFIG_ENV_SIZE;
|
||||
ret = mmc_write((u_char *)env_ptr, CONFIG_ENV_OFFSET, total);
|
||||
if (ret || total != CONFIG_ENV_SIZE) {
|
||||
puts("failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
puts("done\n");
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_ENV_OFFSET_REDUND */
|
||||
#endif /* CMD_SAVEENV */
|
||||
|
||||
#ifdef CONFIG_ENV_OFFSET_REDUND
|
||||
void env_relocate_spec(void)
|
||||
{
|
||||
#if !defined(ENV_IS_EMBEDDED)
|
||||
size_t total;
|
||||
int crc1_ok = 0, crc2_ok = 0;
|
||||
env_t *tmp_env1 = NULL, *tmp_env2 = NULL;
|
||||
|
||||
puts("Initialing MMC card... \n");
|
||||
|
||||
if (mmc_init(1) != 0) {
|
||||
puts("No MMC card found\n");
|
||||
goto use_default;
|
||||
}
|
||||
|
||||
total = CONFIG_ENV_SIZE;
|
||||
|
||||
tmp_env1 = (env_t *)malloc(CONFIG_ENV_SIZE);
|
||||
if (!tmp_env1) {
|
||||
puts("Not enough memory!\n");
|
||||
goto use_default;
|
||||
}
|
||||
memset(tmp_env1, 0, CONFIG_ENV_SIZE);
|
||||
|
||||
tmp_env2 = (env_t *)malloc(CONFIG_ENV_SIZE);
|
||||
if (!tmp_env2) {
|
||||
puts("Not enough memory!\n");
|
||||
goto use_default;
|
||||
}
|
||||
memset(tmp_env2, 0, CONFIG_ENV_SIZE);
|
||||
|
||||
puts("Loading environment from mmc... ");
|
||||
if (mmc_read(CONFIG_ENV_OFFSET, (uchar *)tmp_env1, total)) {
|
||||
puts("failed\n");
|
||||
goto use_default;
|
||||
}
|
||||
puts("done\n");
|
||||
|
||||
puts("Loading redundant environment from mmc... ");
|
||||
if (mmc_read(CONFIG_ENV_OFFSET_REDUND, (uchar *)tmp_env2, total)) {
|
||||
puts("failed\n");
|
||||
goto use_default;
|
||||
}
|
||||
puts("done\n");
|
||||
|
||||
crc1_ok = (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc);
|
||||
crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc);
|
||||
|
||||
if (!crc1_ok && !crc2_ok)
|
||||
goto use_default;
|
||||
else if (crc1_ok && !crc2_ok)
|
||||
gd->env_valid = 1;
|
||||
else if (!crc1_ok && crc2_ok)
|
||||
gd->env_valid = 2;
|
||||
else {
|
||||
/* both ok - check serial */
|
||||
if (tmp_env1->flags == 255 && tmp_env2->flags == 0)
|
||||
gd->env_valid = 2;
|
||||
else if (tmp_env2->flags == 255 && tmp_env1->flags == 0)
|
||||
gd->env_valid = 1;
|
||||
else if (tmp_env1->flags > tmp_env2->flags)
|
||||
gd->env_valid = 1;
|
||||
else if (tmp_env2->flags > tmp_env1->flags)
|
||||
gd->env_valid = 2;
|
||||
else /* flags are equal - almost impossible */
|
||||
gd->env_valid = 1;
|
||||
}
|
||||
|
||||
free(env_ptr);
|
||||
if (gd->env_valid == 1) {
|
||||
env_ptr = tmp_env1;
|
||||
free(tmp_env2);
|
||||
} else {
|
||||
env_ptr = tmp_env2;
|
||||
free(tmp_env1);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
use_default:
|
||||
if (tmp_env1)
|
||||
free(tmp_env1);
|
||||
if (tmp_env2)
|
||||
free(tmp_env2);
|
||||
return use_default();
|
||||
|
||||
#endif /* ! ENV_IS_EMBEDDED */
|
||||
}
|
||||
#else /* ! CONFIG_ENV_OFFSET_REDUND */
|
||||
/*
|
||||
* The legacy NAND code saved the environment in the first NAND device i.e.,
|
||||
* nand_dev_desc + 0. This is also the behaviour using the new NAND code.
|
||||
*/
|
||||
void env_relocate_spec(void)
|
||||
{
|
||||
#if !defined(ENV_IS_EMBEDDED)
|
||||
size_t total;
|
||||
int ret;
|
||||
|
||||
if (mmc_init(1) != 0) {
|
||||
puts("No MMC card found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
total = CONFIG_ENV_SIZE;
|
||||
ret = mmc_read(CONFIG_ENV_OFFSET, (u_char *)env_ptr, total);
|
||||
if (ret || total != CONFIG_ENV_SIZE)
|
||||
return use_default();
|
||||
|
||||
if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc)
|
||||
return use_default();
|
||||
#endif /* ! ENV_IS_EMBEDDED */
|
||||
}
|
||||
#endif /* CONFIG_ENV_OFFSET_REDUND */
|
||||
|
||||
#if !defined(ENV_IS_EMBEDDED)
|
||||
static void use_default()
|
||||
{
|
||||
puts("*** Warning - bad CRC or MMC Card, using default environment\n\n");
|
||||
|
||||
if (default_environment_size > CONFIG_ENV_SIZE) {
|
||||
puts("*** Error - default environment is too large\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(env_ptr, 0, sizeof(env_t));
|
||||
memcpy(env_ptr->data,
|
||||
default_environment,
|
||||
default_environment_size);
|
||||
env_ptr->crc = crc32(0, env_ptr->data, ENV_SIZE);
|
||||
gd->env_valid = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_ENV_IS_IN_MMC */
|
||||
@ -124,6 +124,12 @@ gccincdir := $(shell $(CC) -print-file-name=include)
|
||||
|
||||
CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \
|
||||
-D__KERNEL__
|
||||
|
||||
ifneq ($(BOOT_MEDIA),)
|
||||
BOOT_MEDIA_MACRO = BOOT_MEDIA_$(shell echo $(BOOT_MEDIA) | tr '[a-z]' '[A-Z]')
|
||||
CPPFLAGS += -D$(BOOT_MEDIA_MACRO)
|
||||
endif
|
||||
|
||||
ifneq ($(TEXT_BASE),)
|
||||
CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
|
||||
endif
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
* (C) Copyright 2002
|
||||
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
|
||||
*
|
||||
* (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
@ -127,6 +129,10 @@ int cleanup_before_linux (void)
|
||||
i = 0;
|
||||
asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); /* invalidate both caches and flush btb */
|
||||
asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (i)); /* mem barrier to sync things */
|
||||
/*Workaround to enable L2CC during kernel decompressing*/
|
||||
#ifdef fixup_before_linux
|
||||
fixup_before_linux;
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,8 @@ LIB = $(obj)lib$(SOC).a
|
||||
|
||||
COBJS = interrupts.o serial.o generic.o
|
||||
|
||||
SOBJS = nand_load.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
* (C) Copyright 2007
|
||||
* Sascha Hauer, Pengutronix
|
||||
*
|
||||
@ -34,10 +35,11 @@
|
||||
#define GPTCNT __REG(TIMER_BASE + 0x24) /* Counter register */
|
||||
|
||||
/* General purpose timers bitfields */
|
||||
#define GPTCR_SWR (1 << 15) /* Software reset */
|
||||
#define GPTCR_FRR (1 << 9) /* Freerun / restart */
|
||||
#define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source */
|
||||
#define GPTCR_TEN 1 /* Timer enable */
|
||||
#define GPTCR_SWR (1<<15) /* Software reset */
|
||||
#define GPTCR_FRR (1<<9) /* Freerun / restart */
|
||||
#define GPTCR_CLKSOURCE_32 (4<<6) /* Clock source */
|
||||
#define GPTCR_TEN (1) /* Timer enable */
|
||||
#define GPTCR_ENMODE (1<<1) /* gpt enable mode */
|
||||
|
||||
static ulong timestamp;
|
||||
static ulong lastinc;
|
||||
@ -93,15 +95,13 @@ static inline unsigned long long us_to_tick(unsigned long long us)
|
||||
/* The 32768Hz 32-bit timer overruns in 131072 seconds */
|
||||
int interrupt_init (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* setup GP Timer 1 */
|
||||
GPTCR = GPTCR_SWR;
|
||||
for (i = 0; i < 100; i++)
|
||||
GPTCR = 0; /* We have no udelay by now */
|
||||
while (GPTCR & GPTCR_SWR)
|
||||
;
|
||||
GPTPR = 0; /* 32Khz */
|
||||
/* Freerun Mode, PERCLK1 input */
|
||||
GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN;
|
||||
GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN | GPTCR_ENMODE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
160
cpu/arm1136/mx31/nand_load.S
Normal file
160
cpu/arm1136/mx31/nand_load.S
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include <asm/arch/mx31-regs.h>
|
||||
|
||||
.section ".text.load", "x"
|
||||
|
||||
.macro wait_op_done
|
||||
1: ldrh r3, [r12, #NAND_FLASH_CONFIG2_REG_OFF]
|
||||
ands r3, r3, #NAND_FLASH_CONFIG2_INT_DONE
|
||||
beq 1b
|
||||
.endm
|
||||
|
||||
data_output:
|
||||
strh r8, [r12, #RAM_BUFFER_ADDRESS_REG_OFF]
|
||||
mov r3, #FDO_PAGE_SPARE_VAL
|
||||
strh r3, [r12, #NAND_FLASH_CONFIG2_REG_OFF]
|
||||
wait_op_done
|
||||
bx lr
|
||||
|
||||
send_addr:
|
||||
strh r3, [r12, #NAND_FLASH_ADD_REG_OFF]
|
||||
mov r3, #NAND_FLASH_CONFIG2_FADD_EN
|
||||
strh r3, [r12, #NAND_FLASH_CONFIG2_REG_OFF]
|
||||
wait_op_done
|
||||
bx lr
|
||||
|
||||
send_cmd:
|
||||
strh r3, [r12, #NAND_FLASH_CMD_REG_OFF]
|
||||
mov r3, #NAND_FLASH_CONFIG2_FCMD_EN
|
||||
strh r3, [r12, #NAND_FLASH_CONFIG2_REG_OFF]
|
||||
wait_op_done
|
||||
bx lr
|
||||
|
||||
|
||||
nand_read_page:
|
||||
|
||||
mov r7, lr
|
||||
|
||||
mov r3, #0x0
|
||||
/* send command */
|
||||
bl send_cmd
|
||||
/* 5 cycles address input */
|
||||
mov r3, #0x0
|
||||
bl send_addr
|
||||
mov r3, #0x0
|
||||
bl send_addr
|
||||
mov r3, r0
|
||||
bl send_addr
|
||||
mov r3, #0x0
|
||||
bl send_addr
|
||||
mov r3, #0x0
|
||||
bl send_addr
|
||||
/* confirm read */
|
||||
mov r3, #0x30
|
||||
bl send_cmd
|
||||
/* data output */
|
||||
mov r8, #0x0
|
||||
mov r4, #0x4
|
||||
1:
|
||||
bl data_output
|
||||
add r8, r8, #0x01
|
||||
cmp r8, r4
|
||||
bne 1b
|
||||
ldrh r3, [r12, #ECC_STATUS_RESULT_REG_OFF]
|
||||
tst r3, #0x0a
|
||||
bne .
|
||||
mov pc, r7
|
||||
|
||||
.global mxc_nand_load
|
||||
mxc_nand_load:
|
||||
|
||||
/* Copy image from flash to SDRAM first */
|
||||
mov r0, #NFC_BASE_ADDR
|
||||
add r12, r0, #0xE00 /* register */
|
||||
add r2, r0, #0x800 /* 2K */
|
||||
ldr r1, __TEXT_BASE
|
||||
|
||||
1: ldmia r0!, {r3-r10}
|
||||
stmia r1!, {r3-r10}
|
||||
cmp r0, r2
|
||||
blo 1b
|
||||
/* Jump to SDRAM */
|
||||
ldr r1, =0x0FFF
|
||||
and r0, pc, r1 /* offset of pc */
|
||||
ldr r1, __TEXT_BASE
|
||||
add r1, r1, #0x10
|
||||
add pc, r0, r1
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
nand_copy_block:
|
||||
|
||||
/* wait for boot complete */
|
||||
4:
|
||||
ldrh r3, [r12, #NAND_FLASH_CONFIG2_REG_OFF]
|
||||
tst r3, #0x8000
|
||||
beq 4b
|
||||
|
||||
/* unlock buffer and blocks */
|
||||
mov r3, #0x02
|
||||
strh r3, [r12, #NFC_CONFIGURATION_REG_OFF]
|
||||
mov r3, #0x0
|
||||
strh r3, [r12, #UNLOCK_START_BLK_ADD_REG_OFF]
|
||||
mov r3, #0x800
|
||||
strh r3, [r12, #UNLOCK_END_BLK_ADD_REG_OFF]
|
||||
mov r3, #0x04
|
||||
strh r3, [r12, #NF_WR_PROT_REG_OFF]
|
||||
mov r3, #0x10
|
||||
strh r3, [r12, #NAND_FLASH_CONFIG1_REG_OFF]
|
||||
|
||||
/* read 1 block, 256K */
|
||||
mov r0, #0x01 /* page offset */
|
||||
ldr r11, __TEXT_BASE
|
||||
add r11, r11, #0x800
|
||||
|
||||
mov r1, #NFC_BASE_ADDR
|
||||
add r2, r1, #0x800
|
||||
2:
|
||||
bl nand_read_page /* r0, r1, r2, r11 has been used */
|
||||
/* copy data from internal buffer */
|
||||
3: ldmia r1!, {r3-r10}
|
||||
stmia r11!, {r3-r10}
|
||||
cmp r1, r2
|
||||
blo 3b
|
||||
|
||||
add r0, r0, #0x01
|
||||
cmp r0, #0x80
|
||||
mov r1, #NFC_BASE_ADDR
|
||||
bne 2b
|
||||
|
||||
/* set pc to _set_env */
|
||||
ldr r11, __TEXT_BASE
|
||||
ldr r1, =0x7FF
|
||||
/* correct the lr */
|
||||
and r13, r13, r1
|
||||
add r13, r13, r11
|
||||
mov pc, r13
|
||||
|
||||
__TEXT_BASE:
|
||||
.word TEXT_BASE
|
||||
48
cpu/arm1136/mx35/Makefile
Normal file
48
cpu/arm1136/mx35/Makefile
Normal file
@ -0,0 +1,48 @@
|
||||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
#
|
||||
# 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 = interrupts.o serial.o generic.o iomux.o
|
||||
SOBJS = mxc_nand_load.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
|
||||
|
||||
#########################################################################
|
||||
258
cpu/arm1136/mx35/crm_regs.h
Normal file
258
cpu/arm1136/mx35/crm_regs.h
Normal file
@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
#ifndef __CPU_ARM1136_MX35_CRM_REGS_H__
|
||||
#define __CPU_ARM1136_MX35_CRM_REGS_H__
|
||||
|
||||
/* Register bit definitions */
|
||||
#define MXC_CCM_CCMR_WFI (1 << 30)
|
||||
#define MXC_CCM_CCMR_STBY_EXIT_SRC (1 << 29)
|
||||
#define MXC_CCM_CCMR_VSTBY (1 << 28)
|
||||
#define MXC_CCM_CCMR_WBEN (1 << 27)
|
||||
#define MXC_CCM_CCMR_VOL_RDY_CNT_OFFSET 20
|
||||
#define MXC_CCM_CCMR_VOL_RDY_CNT_MASK (0xF << 20)
|
||||
#define MXC_CCM_CCMR_ROMW_OFFSET 18
|
||||
#define MXC_CCM_CCMR_ROMW_MASK (0x3 << 18)
|
||||
#define MXC_CCM_CCMR_RAMW_OFFSET 21
|
||||
#define MXC_CCM_CCMR_RAMW_MASK (0x3 << 21)
|
||||
#define MXC_CCM_CCMR_LPM_OFFSET 14
|
||||
#define MXC_CCM_CCMR_LPM_MASK (0x3 << 14)
|
||||
#define MXC_CCM_CCMR_UPE (1 << 9)
|
||||
#define MXC_CCM_CCMR_MPE (1 << 3)
|
||||
|
||||
#define MXC_CCM_PDR0_PER_SEL (1 << 26)
|
||||
#define MXC_CCM_PDR0_IPU_HND_BYP (1 << 23)
|
||||
#define MXC_CCM_PDR0_HSP_PODF_OFFSET 20
|
||||
#define MXC_CCM_PDR0_HSP_PODF_MASK (0x3 << 20)
|
||||
#define MXC_CCM_PDR0_CON_MUX_DIV_OFFSET 16
|
||||
#define MXC_CCM_PDR0_CON_MUX_DIV_MASK (0xF << 16)
|
||||
#define MXC_CCM_PDR0_CKIL_SEL (1 << 15)
|
||||
#define MXC_CCM_PDR0_PER_PODF_OFFSET 12
|
||||
#define MXC_CCM_PDR0_PER_PODF_MASK (0xF << 12)
|
||||
#define MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET 9
|
||||
#define MXC_CCM_PDR0_AUTO_MUX_DIV_MASK (0x7 << 9)
|
||||
#define MXC_CCM_PDR0_AUTO_CON 0x1
|
||||
|
||||
#define MXC_CCM_PDR1_MSHC_PRDF_OFFSET 28
|
||||
#define MXC_CCM_PDR1_MSHC_PRDF_MASK (0x7 << 28)
|
||||
#define MXC_CCM_PDR1_MSHC_PODF_OFFSET 22
|
||||
#define MXC_CCM_PDR1_MSHC_PODF_MASK (0x3F << 22)
|
||||
#define MXC_CCM_PDR1_MSHC_M_U (1 << 7)
|
||||
|
||||
#define MXC_CCM_PDR2_SSI2_PRDF_OFFSET 27
|
||||
#define MXC_CCM_PDR2_SSI2_PRDF_MASK (0x7 << 27)
|
||||
#define MXC_CCM_PDR2_SSI1_PRDF_OFFSET 24
|
||||
#define MXC_CCM_PDR2_SSI1_PRDF_MASK (0x7 << 24)
|
||||
#define MXC_CCM_PDR2_CSI_PRDF_OFFSET 19
|
||||
#define MXC_CCM_PDR2_CSI_PRDF_MASK (0x7 << 19)
|
||||
#define MXC_CCM_PDR2_CSI_PODF_OFFSET 16
|
||||
#define MXC_CCM_PDR2_CSI_PODF_MASK (0x7 << 16)
|
||||
#define MXC_CCM_PDR2_SSI2_PODF_OFFSET 8
|
||||
#define MXC_CCM_PDR2_SSI2_PODF_MASK (0x3F << 8)
|
||||
#define MXC_CCM_PDR2_CSI_M_U (1 << 7)
|
||||
#define MXC_CCM_PDR2_SSI_M_U (1 << 6)
|
||||
#define MXC_CCM_PDR2_SSI1_PODF_OFFSET 0
|
||||
#define MXC_CCM_PDR2_SSI1_PODF_MASK (0x3F)
|
||||
|
||||
#define MXC_CCM_PDR3_SPDIF_PRDF_OFFSET 29
|
||||
#define MXC_CCM_PDR3_SPDIF_PRDF_MASK (0x7 << 29)
|
||||
#define MXC_CCM_PDR3_SPDIF_PODF_OFFSET 23
|
||||
#define MXC_CCM_PDR3_SPDIF_PODF_MASK (0x3F << 23)
|
||||
#define MXC_CCM_PDR3_SPDIF_M_U (1 << 22)
|
||||
#define MXC_CCM_PDR3_ESDHC3_PRDF_OFFSET 19
|
||||
#define MXC_CCM_PDR3_ESDHC3_PRDF_MASK (0x7 << 19)
|
||||
#define MXC_CCM_PDR3_ESDHC3_PODF_OFFSET 16
|
||||
#define MXC_CCM_PDR3_ESDHC3_PODF_MASK (0x7 << 16)
|
||||
#define MXC_CCM_PDR3_UART_M_U (1 << 15)
|
||||
#define MXC_CCM_PDR3_ESDHC2_PRDF_OFFSET 11
|
||||
#define MXC_CCM_PDR3_ESDHC2_PRDF_MASK (0x7 << 11)
|
||||
#define MXC_CCM_PDR3_ESDHC2_PODF_OFFSET 8
|
||||
#define MXC_CCM_PDR3_ESDHC2_PODF_MASK (0x7 << 8)
|
||||
#define MXC_CCM_PDR3_ESDHC_M_U (1 << 6)
|
||||
#define MXC_CCM_PDR3_ESDHC1_PRDF_OFFSET 3
|
||||
#define MXC_CCM_PDR3_ESDHC1_PRDF_MASK (0x7 << 3)
|
||||
#define MXC_CCM_PDR3_ESDHC1_PODF_OFFSET 0
|
||||
#define MXC_CCM_PDR3_ESDHC1_PODF_MASK (0x7)
|
||||
|
||||
#define MXC_CCM_PDR4_NFC_PODF_OFFSET 28
|
||||
#define MXC_CCM_PDR4_NFC_PODF_MASK (0xF << 28)
|
||||
#define MXC_CCM_PDR4_USB_PRDF_OFFSET 25
|
||||
#define MXC_CCM_PDR4_USB_PRDF_MASK (0x7 << 25)
|
||||
#define MXC_CCM_PDR4_USB_PODF_OFFSET 22
|
||||
#define MXC_CCM_PDR4_USB_PODF_MASK (0x7 << 22)
|
||||
#define MXC_CCM_PDR4_PER0_PRDF_OFFSET 19
|
||||
#define MXC_CCM_PDR4_PER0_PRDF_MASK (0x7 << 19)
|
||||
#define MXC_CCM_PDR4_PER0_PODF_OFFSET 16
|
||||
#define MXC_CCM_PDR4_PER0_PODF_MASK (0x7 << 16)
|
||||
#define MXC_CCM_PDR4_UART_PRDF_OFFSET 13
|
||||
#define MXC_CCM_PDR4_UART_PRDF_MASK (0x7 << 13)
|
||||
#define MXC_CCM_PDR4_UART_PODF_OFFSET 10
|
||||
#define MXC_CCM_PDR4_UART_PODF_MASK (0x7 << 10)
|
||||
#define MXC_CCM_PDR4_USB_M_U (1 << 9)
|
||||
|
||||
/* Bit definitions for RCSR */
|
||||
#define MXC_CCM_RCSR_BUS_WIDTH (1 << 29)
|
||||
#define MXC_CCM_RCSR_BUS_16BIT (1 << 29)
|
||||
#define MXC_CCM_RCSR_PAGE_SIZE (3 << 27)
|
||||
#define MXC_CCM_RCSR_PAGE_512 (0 << 27)
|
||||
#define MXC_CCM_RCSR_PAGE_2K (1 << 27)
|
||||
#define MXC_CCM_RCSR_PAGE_4K1 (2 << 27)
|
||||
#define MXC_CCM_RCSR_PAGE_4K2 (3 << 27)
|
||||
#define MXC_CCM_RCSR_SOFT_RESET (1 << 15)
|
||||
#define MXC_CCM_RCSR_NF16B (1 << 14)
|
||||
#define MXC_CCM_RCSR_NFC_4K (1 << 9)
|
||||
#define MXC_CCM_RCSR_NFC_FMS (1 << 8)
|
||||
|
||||
/* Bit definitions for both MCU, PERIPHERAL PLL control registers */
|
||||
#define MXC_CCM_PCTL_BRM 0x80000000
|
||||
#define MXC_CCM_PCTL_PD_OFFSET 26
|
||||
#define MXC_CCM_PCTL_PD_MASK (0xF << 26)
|
||||
#define MXC_CCM_PCTL_MFD_OFFSET 16
|
||||
#define MXC_CCM_PCTL_MFD_MASK (0x3FF << 16)
|
||||
#define MXC_CCM_PCTL_MFI_OFFSET 10
|
||||
#define MXC_CCM_PCTL_MFI_MASK (0xF << 10)
|
||||
#define MXC_CCM_PCTL_MFN_OFFSET 0
|
||||
#define MXC_CCM_PCTL_MFN_MASK 0x3FF
|
||||
|
||||
/* Bit definitions for Audio clock mux register*/
|
||||
#define MXC_CCM_ACMR_ESAI_CLK_SEL_OFFSET 12
|
||||
#define MXC_CCM_ACMR_ESAI_CLK_SEL_MASK (0xF << 12)
|
||||
#define MXC_CCM_ACMR_SPDIF_CLK_SEL_OFFSET 8
|
||||
#define MXC_CCM_ACMR_SPDIF_CLK_SEL_MASK (0xF << 8)
|
||||
#define MXC_CCM_ACMR_SSI1_CLK_SEL_OFFSET 4
|
||||
#define MXC_CCM_ACMR_SSI1_CLK_SEL_MASK (0xF << 4)
|
||||
#define MXC_CCM_ACMR_SSI2_CLK_SEL_OFFSET 0
|
||||
#define MXC_CCM_ACMR_SSI2_CLK_SEL_MASK (0xF << 0)
|
||||
|
||||
/* Bit definitions for Clock gating Register*/
|
||||
#define MXC_CCM_CGR0_ASRC_OFFSET 0
|
||||
#define MXC_CCM_CGR0_ASRC_MASK (0x3 << 0)
|
||||
#define MXC_CCM_CGR0_ATA_OFFSET 2
|
||||
#define MXC_CCM_CGR0_ATA_MASK (0x3 << 2)
|
||||
#define MXC_CCM_CGR0_CAN1_OFFSET 6
|
||||
#define MXC_CCM_CGR0_CAN1_MASK (0x3 << 6)
|
||||
#define MXC_CCM_CGR0_CAN2_OFFSET 8
|
||||
#define MXC_CCM_CGR0_CAN2_MASK (0x3 << 8)
|
||||
#define MXC_CCM_CGR0_CSPI1_OFFSET 10
|
||||
#define MXC_CCM_CGR0_CSPI1_MASK (0x3 << 10)
|
||||
#define MXC_CCM_CGR0_CSPI2_OFFSET 12
|
||||
#define MXC_CCM_CGR0_CSPI2_MASK (0x3 << 12)
|
||||
#define MXC_CCM_CGR0_ECT_OFFSET 14
|
||||
#define MXC_CCM_CGR0_ECT_MASK (0x3 << 14)
|
||||
#define MXC_CCM_CGR0_EMI_OFFSET 18
|
||||
#define MXC_CCM_CGR0_EMI_MASK (0x3 << 18)
|
||||
#define MXC_CCM_CGR0_EPIT1_OFFSET 20
|
||||
#define MXC_CCM_CGR0_EPIT1_MASK (0x3 << 20)
|
||||
#define MXC_CCM_CGR0_EPIT2_OFFSET 22
|
||||
#define MXC_CCM_CGR0_EPIT2_MASK (0x3 << 22)
|
||||
#define MXC_CCM_CGR0_ESAI_OFFSET 24
|
||||
#define MXC_CCM_CGR0_ESAI_MASK (0x3 << 24)
|
||||
#define MXC_CCM_CGR0_ESDHC1_OFFSET 26
|
||||
#define MXC_CCM_CGR0_ESDHC1_MASK (0x3 << 26)
|
||||
#define MXC_CCM_CGR0_ESDHC2_OFFSET 28
|
||||
#define MXC_CCM_CGR0_ESDHC2_MASK (0x3 << 28)
|
||||
#define MXC_CCM_CGR0_ESDHC3_OFFSET 30
|
||||
#define MXC_CCM_CGR0_ESDHC3_MASK (0x3 << 30)
|
||||
|
||||
#define MXC_CCM_CGR1_FEC_OFFSET 0
|
||||
#define MXC_CCM_CGR1_FEC_MASK (0x3 << 0)
|
||||
#define MXC_CCM_CGR1_GPIO1_OFFSET 2
|
||||
#define MXC_CCM_CGR1_GPIO1_MASK (0x3 << 2)
|
||||
#define MXC_CCM_CGR1_GPIO2_OFFSET 4
|
||||
#define MXC_CCM_CGR1_GPIO2_MASK (0x3 << 4)
|
||||
#define MXC_CCM_CGR1_GPIO3_OFFSET 6
|
||||
#define MXC_CCM_CGR1_GPIO3_MASK (0x3 << 6)
|
||||
#define MXC_CCM_CGR1_GPT_OFFSET 8
|
||||
#define MXC_CCM_CGR1_GPT_MASK (0x3 << 8)
|
||||
#define MXC_CCM_CGR1_I2C1_OFFSET 10
|
||||
#define MXC_CCM_CGR1_I2C1_MASK (0x3 << 10)
|
||||
#define MXC_CCM_CGR1_I2C2_OFFSET 12
|
||||
#define MXC_CCM_CGR1_I2C2_MASK (0x3 << 12)
|
||||
#define MXC_CCM_CGR1_I2C3_OFFSET 14
|
||||
#define MXC_CCM_CGR1_I2C3_MASK (0x3 << 14)
|
||||
#define MXC_CCM_CGR1_IOMUXC_OFFSET 16
|
||||
#define MXC_CCM_CGR1_IOMUXC_MASK (0x3 << 16)
|
||||
#define MXC_CCM_CGR1_IPU_OFFSET 18
|
||||
#define MXC_CCM_CGR1_IPU_MASK (0x3 << 18)
|
||||
#define MXC_CCM_CGR1_KPP_OFFSET 20
|
||||
#define MXC_CCM_CGR1_KPP_MASK (0x3 << 20)
|
||||
#define MXC_CCM_CGR1_MLB_OFFSET 22
|
||||
#define MXC_CCM_CGR1_MLB_MASK (0x3 << 22)
|
||||
#define MXC_CCM_CGR1_MSHC_OFFSET 24
|
||||
#define MXC_CCM_CGR1_MSHC_MASK (0x3 << 24)
|
||||
#define MXC_CCM_CGR1_OWIRE_OFFSET 26
|
||||
#define MXC_CCM_CGR1_OWIRE_MASK (0x3 << 26)
|
||||
#define MXC_CCM_CGR1_PWM_OFFSET 28
|
||||
#define MXC_CCM_CGR1_PWM_MASK (0x3 << 28)
|
||||
#define MXC_CCM_CGR1_RNGC_OFFSET 30
|
||||
#define MXC_CCM_CGR1_RNGC_MASK (0x3 << 30)
|
||||
|
||||
#define MXC_CCM_CGR2_RTC_OFFSET 0
|
||||
#define MXC_CCM_CGR2_RTC_MASK (0x3 << 0)
|
||||
#define MXC_CCM_CGR2_RTIC_OFFSET 2
|
||||
#define MXC_CCM_CGR2_RTIC_MASK (0x3 << 2)
|
||||
#define MXC_CCM_CGR2_SCC_OFFSET 4
|
||||
#define MXC_CCM_CGR2_SCC_MASK (0x3 << 4)
|
||||
#define MXC_CCM_CGR2_SDMA_OFFSET 6
|
||||
#define MXC_CCM_CGR2_SDMA_MASK (0x3 << 6)
|
||||
#define MXC_CCM_CGR2_SPBA_OFFSET 8
|
||||
#define MXC_CCM_CGR2_SPBA_MASK (0x3 << 8)
|
||||
#define MXC_CCM_CGR2_SPDIF_OFFSET 10
|
||||
#define MXC_CCM_CGR2_SPDIF_MASK (0x3 << 10)
|
||||
#define MXC_CCM_CGR2_SSI1_OFFSET 12
|
||||
#define MXC_CCM_CGR2_SSI1_MASK (0x3 << 12)
|
||||
#define MXC_CCM_CGR2_SSI2_OFFSET 14
|
||||
#define MXC_CCM_CGR2_SSI2_MASK (0x3 << 14)
|
||||
#define MXC_CCM_CGR2_UART1_OFFSET 16
|
||||
#define MXC_CCM_CGR2_UART1_MASK (0x3 << 16)
|
||||
#define MXC_CCM_CGR2_UART2_OFFSET 18
|
||||
#define MXC_CCM_CGR2_UART2_MASK (0x3 << 18)
|
||||
#define MXC_CCM_CGR2_UART3_OFFSET 20
|
||||
#define MXC_CCM_CGR2_UART3_MASK (0x3 << 20)
|
||||
#define MXC_CCM_CGR2_USBOTG_OFFSET 22
|
||||
#define MXC_CCM_CGR2_USBOTG_MASK (0x3 << 22)
|
||||
#define MXC_CCM_CGR2_WDOG_OFFSET 24
|
||||
#define MXC_CCM_CGR2_WDOG_MASK (0x3 << 24)
|
||||
#define MXC_CCM_CGR2_MAX_OFFSET 26
|
||||
#define MXC_CCM_CGR2_MAX_MASK (0x3 << 26)
|
||||
#define MXC_CCM_CGR2_MAX_ENABLE (0x2 << 26)
|
||||
#define MXC_CCM_CGR2_AUDMUX_OFFSET 30
|
||||
#define MXC_CCM_CGR2_AUDMUX_MASK (0x3 << 30)
|
||||
|
||||
#define MXC_CCM_CGR3_CSI_OFFSET 0
|
||||
#define MXC_CCM_CGR3_CSI_MASK (0x3 << 0)
|
||||
#define MXC_CCM_CGR3_IIM_OFFSET 2
|
||||
#define MXC_CCM_CGR3_IIM_MASK (0x3 << 2)
|
||||
#define MXC_CCM_CGR3_GPU2D_OFFSET 4
|
||||
#define MXC_CCM_CGR3_GPU2D_MASK (0x3 << 4)
|
||||
|
||||
#define MXC_CCM_COSR_CLKOSEL_MASK 0x1F
|
||||
#define MXC_CCM_COSR_CLKOSEL_OFFSET 0
|
||||
#define MXC_CCM_COSR_CLKOEN (1 << 5)
|
||||
#define MXC_CCM_COSR_CLKOUTDIV_1 (1 << 6)
|
||||
#define MXC_CCM_COSR_CLKOUT_PREDIV_MASK (0x7 << 10)
|
||||
#define MXC_CCM_COSR_CLKOUT_PREDIV_OFFSET 10
|
||||
#define MXC_CCM_COSR_CLKOUT_PRODIV_MASK (0x7 << 13)
|
||||
#define MXC_CCM_COSR_CLKOUT_PRODIV_OFFSET 13
|
||||
#define MXC_CCM_COSR_SSI1_RX_SRC_SEL_MASK (0x3 << 16)
|
||||
#define MXC_CCM_COSR_SSI1_RX_SRC_SEL_OFFSET 16
|
||||
#define MXC_CCM_COSR_SSI1_TX_SRC_SEL_MASK (0x3 << 18)
|
||||
#define MXC_CCM_COSR_SSI1_TX_SRC_SEL_OFFSET 18
|
||||
#define MXC_CCM_COSR_SSI2_RX_SRC_SEL_MASK (0x3 << 20)
|
||||
#define MXC_CCM_COSR_SSI2_RX_SRC_SEL_OFFSET 20
|
||||
#define MXC_CCM_COSR_SSI2_TX_SRC_SEL_MASK (0x3 << 22)
|
||||
#define MXC_CCM_COSR_SSI2_TX_SRC_SEL_OFFSET 22
|
||||
#define MXC_CCM_COSR_ASRC_AUDIO_EN (1 << 24)
|
||||
#define MXC_CCM_COSR_ASRC_AUDIO_PODF_MASK (0x3F << 26)
|
||||
#define MXC_CCM_COSR_ASRC_AUDIO_PODF_OFFSET 26
|
||||
|
||||
#endif /* __CPU_ARM1136_MX35_CRM_REGS_H__ */
|
||||
219
cpu/arm1136/mx35/generic.c
Normal file
219
cpu/arm1136/mx35/generic.c
Normal file
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* (C) Copyright 2007
|
||||
* Sascha Hauer, Pengutronix
|
||||
*
|
||||
* (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <common.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/arch/mx35.h>
|
||||
#include "crm_regs.h"
|
||||
|
||||
#define CLK_CODE(arm, ahb, sel) (((arm) << 16) + ((ahb) << 8) + (sel))
|
||||
#define CLK_CODE_ARM(c) (((c) >> 16) & 0xFF)
|
||||
#define CLK_CODE_AHB(c) (((c) >> 8) & 0xFF)
|
||||
#define CLK_CODE_PATH(c) ((c) & 0xFF)
|
||||
|
||||
#define CCM_GET_DIVIDER(x, m, o) (((x) & (m)) >> (o))
|
||||
|
||||
static int g_clk_mux_auto[8] = {
|
||||
CLK_CODE(1, 3, 0), CLK_CODE(1, 2, 1), CLK_CODE(2, 1, 1), -1,
|
||||
CLK_CODE(1, 6, 0), CLK_CODE(1, 4, 1), CLK_CODE(2, 2, 1), -1,
|
||||
};
|
||||
|
||||
static int g_clk_mux_consumer[16] = {
|
||||
CLK_CODE(1, 4, 0), CLK_CODE(1, 3, 1), CLK_CODE(1, 3, 1), -1,
|
||||
-1, -1, CLK_CODE(4, 1, 0), CLK_CODE(1, 5, 0),
|
||||
CLK_CODE(1, 8, 1), CLK_CODE(1, 6, 1), CLK_CODE(2, 4, 0), -1,
|
||||
-1, -1, CLK_CODE(4, 2, 0), -1,
|
||||
};
|
||||
|
||||
static u32 __get_arm_div(u32 pdr0, u32 *fi, u32 *fd)
|
||||
{
|
||||
int *pclk_mux;
|
||||
if (pdr0 & MXC_CCM_PDR0_AUTO_CON) {
|
||||
pclk_mux = g_clk_mux_consumer +
|
||||
((pdr0 & MXC_CCM_PDR0_CON_MUX_DIV_MASK) >>
|
||||
MXC_CCM_PDR0_CON_MUX_DIV_OFFSET);
|
||||
} else {
|
||||
pclk_mux = g_clk_mux_auto +
|
||||
((pdr0 & MXC_CCM_PDR0_AUTO_MUX_DIV_MASK) >>
|
||||
MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET);
|
||||
}
|
||||
|
||||
if ((*pclk_mux) == -1)
|
||||
return -1;
|
||||
|
||||
if (fi && fd) {
|
||||
if (!CLK_CODE_PATH(*pclk_mux)) {
|
||||
*fi = *fd = 1;
|
||||
return CLK_CODE_ARM(*pclk_mux);
|
||||
}
|
||||
if (pdr0 & MXC_CCM_PDR0_AUTO_CON) {
|
||||
*fi = 3;
|
||||
*fd = 4;
|
||||
} else {
|
||||
*fi = 2;
|
||||
*fd = 3;
|
||||
}
|
||||
}
|
||||
return CLK_CODE_ARM(*pclk_mux);
|
||||
}
|
||||
|
||||
static int __get_ahb_div(u32 pdr0)
|
||||
{
|
||||
int *pclk_mux;
|
||||
if (pdr0 & MXC_CCM_PDR0_AUTO_CON) {
|
||||
pclk_mux = g_clk_mux_consumer +
|
||||
((pdr0 & MXC_CCM_PDR0_CON_MUX_DIV_MASK) >>
|
||||
MXC_CCM_PDR0_CON_MUX_DIV_OFFSET);
|
||||
} else {
|
||||
pclk_mux = g_clk_mux_auto +
|
||||
((pdr0 & MXC_CCM_PDR0_AUTO_MUX_DIV_MASK) >>
|
||||
MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET);
|
||||
}
|
||||
|
||||
if ((*pclk_mux) == -1)
|
||||
return -1;
|
||||
|
||||
return CLK_CODE_AHB(*pclk_mux);
|
||||
}
|
||||
|
||||
static u32 __decode_pll(u32 reg, u32 infreq)
|
||||
{
|
||||
u32 mfi = (reg >> 10) & 0xf;
|
||||
u32 mfn = reg & 0x3f;
|
||||
u32 mfd = (reg >> 16) & 0x3f;
|
||||
u32 pd = (reg >> 26) & 0xf;
|
||||
|
||||
mfi = mfi <= 5 ? 5 : mfi;
|
||||
mfd += 1;
|
||||
pd += 1;
|
||||
|
||||
return ((2 * (infreq / 1000) * (mfi * mfd + mfn)) / (mfd * pd)) * 1000;
|
||||
}
|
||||
|
||||
static u32 __get_mcu_main_clk(void)
|
||||
{
|
||||
u32 arm_div, fi, fd;
|
||||
arm_div = __get_arm_div(__REG(CCM_BASE_ADDR + CLKCTL_PDR0), &fi, &fd);
|
||||
fi *=
|
||||
__decode_pll(__REG(CCM_BASE_ADDR + CLKCTL_MPCTL),
|
||||
CONFIG_MX35_HCLK_FREQ);
|
||||
return fi / (arm_div * fd);
|
||||
}
|
||||
|
||||
static u32 __get_ipg_clk(void)
|
||||
{
|
||||
u32 freq = __get_mcu_main_clk();
|
||||
u32 pdr0 = __REG(CCM_BASE_ADDR + CLKCTL_PDR0);
|
||||
|
||||
return freq / (__get_ahb_div(pdr0) * 2);
|
||||
}
|
||||
|
||||
static u32 __get_ipg_per_clk(void)
|
||||
{
|
||||
u32 freq = __get_mcu_main_clk();
|
||||
u32 pdr0 = __REG(CCM_BASE_ADDR + CLKCTL_PDR0);
|
||||
u32 pdr4 = __REG(CCM_BASE_ADDR + CLKCTL_PDR4);
|
||||
u32 div;
|
||||
if (pdr0 & MXC_CCM_PDR0_PER_SEL) {
|
||||
div = (CCM_GET_DIVIDER(pdr4,
|
||||
MXC_CCM_PDR4_PER0_PRDF_MASK,
|
||||
MXC_CCM_PDR4_PER0_PODF_OFFSET) + 1) *
|
||||
(CCM_GET_DIVIDER(pdr4,
|
||||
MXC_CCM_PDR4_PER0_PODF_MASK,
|
||||
MXC_CCM_PDR4_PER0_PODF_OFFSET) + 1);
|
||||
} else {
|
||||
div = CCM_GET_DIVIDER(pdr0,
|
||||
MXC_CCM_PDR0_PER_PODF_MASK,
|
||||
MXC_CCM_PDR0_PER_PODF_OFFSET) + 1;
|
||||
freq /= __get_ahb_div(pdr0);
|
||||
}
|
||||
return freq / div;
|
||||
}
|
||||
|
||||
static u32 __get_uart_clk(void)
|
||||
{
|
||||
u32 freq;
|
||||
u32 pdr4 = __REG(CCM_BASE_ADDR + CLKCTL_PDR4);
|
||||
|
||||
if (__REG(CCM_BASE_ADDR + CLKCTL_PDR3) & MXC_CCM_PDR3_UART_M_U)
|
||||
freq = __get_mcu_main_clk();
|
||||
else
|
||||
freq = __decode_pll(__REG(CCM_BASE_ADDR + CLKCTL_PPCTL),
|
||||
CONFIG_MX35_HCLK_FREQ);
|
||||
freq /= ((CCM_GET_DIVIDER(pdr4,
|
||||
MXC_CCM_PDR4_UART_PRDF_MASK,
|
||||
MXC_CCM_PDR4_UART_PRDF_OFFSET) + 1) *
|
||||
(CCM_GET_DIVIDER(pdr4,
|
||||
MXC_CCM_PDR4_UART_PODF_MASK,
|
||||
MXC_CCM_PDR4_UART_PODF_OFFSET) + 1));
|
||||
return freq;
|
||||
}
|
||||
|
||||
unsigned int mxc_get_clock(enum mxc_clock clk)
|
||||
{
|
||||
switch (clk) {
|
||||
case MXC_ARM_CLK:
|
||||
return __get_mcu_main_clk();
|
||||
case MXC_AHB_CLK:
|
||||
break;
|
||||
case MXC_IPG_CLK:
|
||||
return __get_ipg_clk();
|
||||
case MXC_IPG_PERCLK:
|
||||
return __get_ipg_per_clk();
|
||||
case MXC_UART_CLK:
|
||||
return __get_uart_clk();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void mxc_dump_clocks(void)
|
||||
{
|
||||
u32 cpufreq = __get_mcu_main_clk();
|
||||
printf("mx35 cpu clock: %dMHz\n", cpufreq / 1000000);
|
||||
printf("ipg clock : %dHz\n", __get_ipg_clk());
|
||||
printf("uart clock : %dHz\n", mxc_get_clock(MXC_UART_CLK));
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DISPLAY_CPUINFO)
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
printf("CPU: Freescale i.MX35 at %d MHz\n",
|
||||
__get_mcu_main_clk() / 1000000);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initializes on-chip ethernet controllers.
|
||||
* to override, implement board_eth_init()
|
||||
*/
|
||||
int cpu_eth_init(bd_t *bis)
|
||||
{
|
||||
int rc = -ENODEV;
|
||||
#if defined(CONFIG_MXC_FEC)
|
||||
rc = mxc_fec_initialize(bis);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
115
cpu/arm1136/mx35/interrupts.c
Normal file
115
cpu/arm1136/mx35/interrupts.c
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* (C) Copyright 2007
|
||||
* Sascha Hauer, Pengutronix
|
||||
*
|
||||
* (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <common.h>
|
||||
#include <asm/arch/mx35.h>
|
||||
|
||||
/* General purpose timers registers */
|
||||
#define GPTCR __REG(GPT1_BASE_ADDR) /* Control register */
|
||||
#define GPTPR __REG(GPT1_BASE_ADDR + 0x4) /* Prescaler register */
|
||||
#define GPTSR __REG(GPT1_BASE_ADDR + 0x8) /* Status register */
|
||||
#define GPTCNT __REG(GPT1_BASE_ADDR + 0x24) /* Counter register */
|
||||
|
||||
/* General purpose timers bitfields */
|
||||
#define GPTCR_SWR (1<<15) /* Software reset */
|
||||
#define GPTCR_FRR (1<<9) /* Freerun / restart */
|
||||
#define GPTCR_CLKSOURCE_32 (4<<6) /* Clock source */
|
||||
#define GPTCR_TEN (1) /* Timer enable */
|
||||
|
||||
/* nothing really to do with interrupts, just starts up a counter. */
|
||||
int interrupt_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* setup GP Timer 1 */
|
||||
GPTCR = GPTCR_SWR;
|
||||
for (i = 0; i < 100; i++)
|
||||
GPTCR = 0; /* We have no udelay by now */
|
||||
GPTPR = 0; /* 32Khz */
|
||||
/* Freerun Mode, PERCLK1 input */
|
||||
GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void reset_timer(void)
|
||||
{
|
||||
reset_timer_masked();
|
||||
}
|
||||
|
||||
void reset_timer_masked(void)
|
||||
{
|
||||
GPTCR = 0;
|
||||
/* Freerun Mode, PERCLK1 input */
|
||||
GPTCR = GPTCR_CLKSOURCE_32 | GPTCR_TEN;
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
ulong val = GPTCNT;
|
||||
return val;
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return get_timer_masked() - base;
|
||||
}
|
||||
|
||||
void set_timer(ulong t)
|
||||
{
|
||||
}
|
||||
|
||||
/* delay x useconds AND perserve advance timstamp value */
|
||||
void udelay(unsigned long usec)
|
||||
{
|
||||
ulong tmo, tmp;
|
||||
|
||||
/* if "big" number, spread normalization to seconds */
|
||||
if (usec >= 1000) {
|
||||
/* start to normalize for usec to ticks per sec */
|
||||
tmo = usec / 1000;
|
||||
/* find number of "ticks" to wait to achieve target */
|
||||
tmo *= CONFIG_SYS_HZ;
|
||||
tmo /= 1000; /* finish normalize. */
|
||||
} else {/* else small number, don't kill it prior to HZ multiply */
|
||||
tmo = usec * CONFIG_SYS_HZ;
|
||||
tmo /= (1000 * 1000);
|
||||
}
|
||||
|
||||
tmp = get_timer(0); /* get current timestamp */
|
||||
/* if setting this forward will roll time stamp */
|
||||
if ((tmo + tmp + 1) < tmp)
|
||||
/* reset "advancing" timestamp to 0, set lastinc value */
|
||||
reset_timer_masked();
|
||||
else /* else, set advancing stamp wake up time */
|
||||
tmo += tmp;
|
||||
while (get_timer_masked() < tmo) /* loop till event */
|
||||
/*NOP*/;
|
||||
}
|
||||
|
||||
void reset_cpu(ulong addr)
|
||||
{
|
||||
__REG16(WDOG_BASE_ADDR) = 4;
|
||||
}
|
||||
149
cpu/arm1136/mx35/iomux.c
Normal file
149
cpu/arm1136/mx35/iomux.c
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @defgroup GPIO_MX35 Board GPIO and Muxing Setup
|
||||
* @ingroup MSL_MX35
|
||||
*/
|
||||
/*!
|
||||
* @file mach-mx35/iomux.c
|
||||
*
|
||||
* @brief I/O Muxing control functions
|
||||
*
|
||||
* @ingroup GPIO_MX35
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <asm/arch/mx35.h>
|
||||
#include <asm/arch/mx35_pins.h>
|
||||
#include <asm/arch/iomux.h>
|
||||
|
||||
/*!
|
||||
* IOMUX register (base) addresses
|
||||
*/
|
||||
enum iomux_reg_addr {
|
||||
IOMUXGPR = IOMUXC_BASE_ADDR,
|
||||
/*!< General purpose */
|
||||
IOMUXSW_MUX_CTL = IOMUXC_BASE_ADDR + 4,
|
||||
/*!< MUX control */
|
||||
IOMUXSW_MUX_END = IOMUXC_BASE_ADDR + 0x324,
|
||||
/*!< last MUX control register */
|
||||
IOMUXSW_PAD_CTL = IOMUXC_BASE_ADDR + 0x328,
|
||||
/*!< Pad control */
|
||||
IOMUXSW_PAD_END = IOMUXC_BASE_ADDR + 0x794,
|
||||
/*!< last Pad control register */
|
||||
IOMUXSW_INPUT_CTL = IOMUXC_BASE_ADDR + 0x7AC,
|
||||
/*!< input select register */
|
||||
IOMUXSW_INPUT_END = IOMUXC_BASE_ADDR + 0x9F4,
|
||||
/*!< last input select register */
|
||||
};
|
||||
|
||||
#define MUX_PIN_NUM_MAX \
|
||||
(((IOMUXSW_PAD_END - IOMUXSW_PAD_CTL) >> 2) + 1)
|
||||
#define MUX_INPUT_NUM_MUX \
|
||||
(((IOMUXSW_INPUT_END - IOMUXSW_INPUT_CTL) >> 2) + 1)
|
||||
|
||||
#define PIN_TO_IOMUX_INDEX(pin) ((PIN_TO_IOMUX_PAD(pin) - 0x328) >> 2)
|
||||
|
||||
/*!
|
||||
* This function is used to configure a pin through the IOMUX module.
|
||||
* FIXED ME: for backward compatible. Will be static function!
|
||||
* @param pin a pin number as defined in \b #iomux_pin_name_t
|
||||
* @param cfg an output function as defined in \b #iomux_pin_cfg_t
|
||||
*
|
||||
* @return 0 if successful; Non-zero otherwise
|
||||
*/
|
||||
static int iomux_config_mux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
|
||||
{
|
||||
u32 mux_reg = PIN_TO_IOMUX_MUX(pin);
|
||||
|
||||
if (mux_reg != NON_MUX_I) {
|
||||
mux_reg += IOMUXGPR;
|
||||
__REG(mux_reg) = cfg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Request ownership for an IO pin. This function has to be the first one
|
||||
* being called before that pin is used. The caller has to check the
|
||||
* return value to make sure it returns 0.
|
||||
*
|
||||
* @param pin a name defined by \b iomux_pin_name_t
|
||||
* @param cfg an input function as defined in \b #iomux_pin_cfg_t
|
||||
*
|
||||
* @return 0 if successful; Non-zero otherwise
|
||||
*/
|
||||
int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
|
||||
{
|
||||
int ret = iomux_config_mux(pin, cfg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Release ownership for an IO pin
|
||||
*
|
||||
* @param pin a name defined by \b iomux_pin_name_t
|
||||
* @param cfg an input function as defined in \b #iomux_pin_cfg_t
|
||||
*/
|
||||
void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function configures the pad value for a IOMUX pin.
|
||||
*
|
||||
* @param pin a pin number as defined in \b #iomux_pin_name_t
|
||||
* @param config the ORed value of elements defined in \b #iomux_pad_config_t
|
||||
*/
|
||||
void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config)
|
||||
{
|
||||
u32 pad_reg = IOMUXGPR + PIN_TO_IOMUX_PAD(pin);
|
||||
|
||||
__REG(pad_reg) = config;
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function enables/disables the general purpose function for a particular
|
||||
* signal.
|
||||
*
|
||||
* @param gp one signal as defined in \b #iomux_gp_func_t
|
||||
* @param en \b #true to enable; \b #false to disable
|
||||
*/
|
||||
void mxc_iomux_set_gpr(iomux_gp_func_t gp, int en)
|
||||
{
|
||||
u32 l;
|
||||
|
||||
l = __REG(IOMUXGPR);
|
||||
if (en)
|
||||
l |= gp;
|
||||
else
|
||||
l &= ~gp;
|
||||
|
||||
__REG(IOMUXGPR) = l;
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function configures input path.
|
||||
*
|
||||
* @param input index of input select register as defined in \b
|
||||
* #iomux_input_select_t
|
||||
* @param config the binary value of elements defined in \b
|
||||
* #iomux_input_config_t
|
||||
*/
|
||||
void mxc_iomux_set_input(iomux_input_select_t input, u32 config)
|
||||
{
|
||||
u32 reg = IOMUXSW_INPUT_CTL + (input << 2);
|
||||
|
||||
__REG(reg) = config;
|
||||
}
|
||||
261
cpu/arm1136/mx35/mxc_nand_load.S
Normal file
261
cpu/arm1136/mx35/mxc_nand_load.S
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
* (C) Copyright 2008 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include <asm/arch/mx35.h>
|
||||
|
||||
.macro nfc_cmd_input
|
||||
strh r3, [r12, #NAND_FLASH_CMD_REG_OFF]
|
||||
mov r3, #NAND_FLASH_CONFIG2_FCMD_EN;
|
||||
strh r3, [r12, #NAND_FLASH_CONFIG2_REG_OFF]
|
||||
bl do_wait_op_done
|
||||
.endm // nfc_cmd_input
|
||||
|
||||
.macro do_addr_input
|
||||
and r3, r3, #0xFF
|
||||
strh r3, [r12, #NAND_FLASH_ADD_REG_OFF]
|
||||
mov r3, #NAND_FLASH_CONFIG2_FADD_EN
|
||||
strh r3, [r12, #NAND_FLASH_CONFIG2_REG_OFF]
|
||||
bl do_wait_op_done
|
||||
.endm // do_addr_input
|
||||
|
||||
.section ".text.load", "x"
|
||||
.globl mxc_nand_load
|
||||
mxc_nand_load:
|
||||
ldr r2, U_BOOT_NAND_START
|
||||
1: ldmia r0!, {r3-r10}
|
||||
stmia r2!, {r3-r10}
|
||||
cmp r0, r1
|
||||
blo 1b
|
||||
|
||||
ldr r1, CONST_0X0FFF
|
||||
ldr r2, U_BOOT_NAND_START
|
||||
and lr, lr, r1
|
||||
add lr, lr, r2
|
||||
and r12, r12, r1
|
||||
add r12, r12, r2
|
||||
add r2, r2, #0x8
|
||||
and r0, pc, r1
|
||||
add pc, r0, r2
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
adr r0, SAVE_REGS
|
||||
str r12, [r0]
|
||||
str lr, [r0, #4]
|
||||
Copy_Main:
|
||||
mov r0, #NFC_BASE_ADDR
|
||||
add r12, r0, #0x1E00
|
||||
ldrh r3, [r12, #NAND_FLASH_CONFIG1_REG_OFF]
|
||||
orr r3, r3, #1
|
||||
|
||||
/* Setting NFC */
|
||||
ldr r7, =CCM_BASE_ADDR
|
||||
ldr r1, [r7, #CLKCTL_RCSR]
|
||||
/*BUS WIDTH setting*/
|
||||
tst r1, #0x20000000
|
||||
orrne r1, r1, #0x4000
|
||||
biceq r1, r1, #0x4000
|
||||
|
||||
/*4K PAGE*/
|
||||
tst r1, #0x10000000
|
||||
orrne r1, r1, #0x200
|
||||
bne 1f
|
||||
/*2K PAGE*/
|
||||
bic r1, r1, #0x200
|
||||
tst r1, #0x08000000
|
||||
orrne r1, r1, #0x100 /*2KB page size*/
|
||||
biceq r1, r1, #0x100 /*512B page size*/
|
||||
movne r2, #32 /*64 bytes*/
|
||||
moveq r2, #8 /*16 bytes*/
|
||||
b NAND_setup
|
||||
1:
|
||||
tst r1, #0x08000000
|
||||
bicne r3, r3, #1 /*Enable 8bit ECC mode*/
|
||||
movne r2, #109 /*218 bytes*/
|
||||
moveq r2, #64 /*128 bytes*/
|
||||
NAND_setup:
|
||||
str r1, [r7, #CLKCTL_RCSR]
|
||||
strh r2, [r12, #ECC_RSLT_SPARE_AREA_REG_OFF]
|
||||
strh r3, [r12, #NAND_FLASH_CONFIG1_REG_OFF]
|
||||
|
||||
//unlock internal buffer
|
||||
mov r3, #0x2
|
||||
strh r3, [r12, #NFC_CONFIGURATION_REG_OFF]
|
||||
//unlock nand device
|
||||
mov r3, #0
|
||||
strh r3, [r12, #UNLOCK_START_BLK_ADD_REG_OFF]
|
||||
sub r3, r3, #1
|
||||
strh r3, [r12, #UNLOCK_END_BLK_ADD_REG_OFF]
|
||||
mov r3, #4
|
||||
strh r3, [r12, #NF_WR_PROT_REG_OFF]
|
||||
|
||||
/* r0: NFC base address. RAM buffer base address. [constantly]
|
||||
* r1: starting flash address to be copied. [constantly]
|
||||
* r2: page size. [Doesn't change]
|
||||
* r3: used as argument.
|
||||
* r11: starting SDRAM address for copying. [Updated constantly].
|
||||
* r12: NFC register base address. [constantly].
|
||||
* r13: end of SDRAM address for copying. [Doesn't change].
|
||||
*/
|
||||
|
||||
mov r1, #0x1000
|
||||
ldr r3, [r7, #CLKCTL_RCSR]
|
||||
tst r3, #0x200
|
||||
movne r2, #0x1000
|
||||
bne 1f
|
||||
tst r3, #0x100
|
||||
mov r1, #0x800 /*Strange Why is not 4K offset*/
|
||||
movne r2, #0x800
|
||||
moveq r2, #0x200
|
||||
1: /*Update the indicator of copy area */
|
||||
ldr r11, U_BOOT_NAND_START
|
||||
add r13, r11, #0x00088000; /*512K + 32K*/
|
||||
add r11, r11, r1
|
||||
|
||||
Nfc_Read_Page:
|
||||
mov r3, #0x0
|
||||
nfc_cmd_input
|
||||
|
||||
cmp r2, #0x800
|
||||
bhi nfc_addr_ops_4kb
|
||||
beq nfc_addr_ops_2kb
|
||||
|
||||
mov r3, r1
|
||||
do_addr_input //1st addr cycle
|
||||
mov r3, r1, lsr #9
|
||||
do_addr_input //2nd addr cycle
|
||||
mov r3, r1, lsr #17
|
||||
do_addr_input //3rd addr cycle
|
||||
mov r3, r1, lsr #25
|
||||
do_addr_input //4th addr cycle
|
||||
b end_of_nfc_addr_ops
|
||||
|
||||
nfc_addr_ops_2kb:
|
||||
mov r3, #0
|
||||
do_addr_input //1st addr cycle
|
||||
mov r3, #0
|
||||
do_addr_input //2nd addr cycle
|
||||
mov r3, r1, lsr #11
|
||||
do_addr_input //3rd addr cycle
|
||||
mov r3, r1, lsr #19
|
||||
do_addr_input //4th addr cycle
|
||||
mov r3, r1, lsr #27
|
||||
do_addr_input //5th addr cycle
|
||||
|
||||
mov r3, #0x30
|
||||
nfc_cmd_input
|
||||
b end_of_nfc_addr_ops
|
||||
|
||||
nfc_addr_ops_4kb:
|
||||
mov r3, #0
|
||||
do_addr_input //1st addr cycle
|
||||
mov r3, #0
|
||||
do_addr_input //2nd addr cycle
|
||||
mov r3, r1, lsr #12
|
||||
do_addr_input //3rd addr cycle
|
||||
mov r3, r1, lsr #20
|
||||
do_addr_input //4th addr cycle
|
||||
mov r3, r1, lsr #27
|
||||
do_addr_input //5th addr cycle
|
||||
|
||||
mov r3, #0x30
|
||||
nfc_cmd_input
|
||||
|
||||
end_of_nfc_addr_ops:
|
||||
mov r8, #0
|
||||
bl nfc_data_output
|
||||
bl do_wait_op_done
|
||||
// Check if x16/2kb page
|
||||
cmp r2, #0x800
|
||||
bhi nfc_addr_data_output_done_4k
|
||||
beq nfc_addr_data_output_done_2k
|
||||
beq nfc_addr_data_output_done_512
|
||||
|
||||
// check for bad block
|
||||
// mov r3, r1, lsl #(32-17) // get rid of block number
|
||||
// cmp r3, #(0x800 << (32-17)) // check if not page 0 or 1
|
||||
b nfc_addr_data_output_done
|
||||
|
||||
nfc_addr_data_output_done_4k:
|
||||
//TODO
|
||||
b nfc_addr_data_output_done
|
||||
|
||||
nfc_addr_data_output_done_2k:
|
||||
// end of 4th
|
||||
// check for bad block
|
||||
//TODO mov r3, r1, lsl #(32-17) // get rid of block number
|
||||
// cmp r3, #(0x800 << (32-17)) // check if not page 0 or 1
|
||||
b nfc_addr_data_output_done
|
||||
|
||||
nfc_addr_data_output_done_512:
|
||||
// check for bad block
|
||||
// TODO mov r3, r1, lsl #(32-5-9) // get rid of block number
|
||||
// TODO cmp r3, #(512 << (32-5-9)) // check if not page 0 or 1
|
||||
|
||||
nfc_addr_data_output_done:
|
||||
Copy_Good_Blk:
|
||||
//copying page
|
||||
add r2, r2, #NFC_BASE_ADDR
|
||||
1: ldmia r0!, {r3-r10}
|
||||
stmia r11!, {r3-r10}
|
||||
cmp r0, r2
|
||||
blo 1b
|
||||
sub r2, r2, #NFC_BASE_ADDR
|
||||
|
||||
cmp r11, r13
|
||||
bge NAND_Copy_Main_done
|
||||
// Check if x16/2kb page
|
||||
add r1, r1, r2
|
||||
mov r0, #NFC_BASE_ADDR
|
||||
b Nfc_Read_Page
|
||||
|
||||
NAND_Copy_Main_done:
|
||||
adr r0, SAVE_REGS
|
||||
ldr r12, [r0]
|
||||
ldr lr, [r0, #4]
|
||||
mov pc, lr
|
||||
|
||||
do_wait_op_done:
|
||||
1:
|
||||
ldrh r3, [r12, #NAND_FLASH_CONFIG2_REG_OFF]
|
||||
ands r3, r3, #NAND_FLASH_CONFIG2_INT_DONE
|
||||
beq 1b
|
||||
bx lr // do
|
||||
|
||||
nfc_data_output:
|
||||
ldrh r3, [r12, #NAND_FLASH_CONFIG1_REG_OFF]
|
||||
orr r3, r3, #(NAND_FLASH_CONFIG1_INT_MSK | NAND_FLASH_CONFIG1_ECC_EN)
|
||||
strh r3, [r12, #NAND_FLASH_CONFIG1_REG_OFF]
|
||||
|
||||
strh r8, [r12, #RAM_BUFFER_ADDRESS_REG_OFF]
|
||||
|
||||
mov r3, #FDO_PAGE_SPARE_VAL
|
||||
strh r3, [r12, #NAND_FLASH_CONFIG2_REG_OFF]
|
||||
bx lr
|
||||
|
||||
U_BOOT_NAND_START: .word TEXT_BASE
|
||||
CONST_0X0FFF: .word 0x0FFF
|
||||
SAVE_REGS: .word 0x0
|
||||
.word 0x0
|
||||
220
cpu/arm1136/mx35/serial.c
Normal file
220
cpu/arm1136/mx35/serial.c
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>
|
||||
*
|
||||
* (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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>
|
||||
|
||||
#if defined CONFIG_MX35_UART
|
||||
|
||||
#include <asm/arch/mx35.h>
|
||||
|
||||
#define __REG(x) (*((volatile u32 *)(x)))
|
||||
|
||||
#define UART_PHYS CONFIG_MX35_UART
|
||||
|
||||
/* Register definitions */
|
||||
#define URXD 0x0 /* Receiver Register */
|
||||
#define UTXD 0x40 /* Transmitter Register */
|
||||
#define UCR1 0x80 /* Control Register 1 */
|
||||
#define UCR2 0x84 /* Control Register 2 */
|
||||
#define UCR3 0x88 /* Control Register 3 */
|
||||
#define UCR4 0x8c /* Control Register 4 */
|
||||
#define UFCR 0x90 /* FIFO Control Register */
|
||||
#define USR1 0x94 /* Status Register 1 */
|
||||
#define USR2 0x98 /* Status Register 2 */
|
||||
#define UESC 0x9c /* Escape Character Register */
|
||||
#define UTIM 0xa0 /* Escape Timer Register */
|
||||
#define UBIR 0xa4 /* BRM Incremental Register */
|
||||
#define UBMR 0xa8 /* BRM Modulator Register */
|
||||
#define UBRC 0xac /* Baud Rate Count Register */
|
||||
#define UTS 0xb4 /* UART Test Register (mx31) */
|
||||
|
||||
/* UART Control Register Bit Fields.*/
|
||||
#define URXD_CHARRDY (1<<15)
|
||||
#define URXD_ERR (1<<14)
|
||||
#define URXD_OVRRUN (1<<13)
|
||||
#define URXD_FRMERR (1<<12)
|
||||
#define URXD_BRK (1<<11)
|
||||
#define URXD_PRERR (1<<10)
|
||||
#define UCR1_ADEN (1<<15) /* Auto dectect interrupt */
|
||||
#define UCR1_ADBR (1<<14) /* Auto detect baud rate */
|
||||
#define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */
|
||||
#define UCR1_IDEN (1<<12) /* Idle condition interrupt */
|
||||
#define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */
|
||||
#define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */
|
||||
#define UCR1_IREN (1<<7) /* Infrared interface enable */
|
||||
#define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */
|
||||
#define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */
|
||||
#define UCR1_SNDBRK (1<<4) /* Send break */
|
||||
#define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */
|
||||
#define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */
|
||||
#define UCR1_DOZE (1<<1) /* Doze */
|
||||
#define UCR1_UARTEN (1<<0) /* UART enabled */
|
||||
#define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */
|
||||
#define UCR2_IRTS (1<<14) /* Ignore RTS pin */
|
||||
#define UCR2_CTSC (1<<13) /* CTS pin control */
|
||||
#define UCR2_CTS (1<<12) /* Clear to send */
|
||||
#define UCR2_ESCEN (1<<11) /* Escape enable */
|
||||
#define UCR2_PREN (1<<8) /* Parity enable */
|
||||
#define UCR2_PROE (1<<7) /* Parity odd/even */
|
||||
#define UCR2_STPB (1<<6) /* Stop */
|
||||
#define UCR2_WS (1<<5) /* Word size */
|
||||
#define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */
|
||||
#define UCR2_TXEN (1<<2) /* Transmitter enabled */
|
||||
#define UCR2_RXEN (1<<1) /* Receiver enabled */
|
||||
#define UCR2_SRST (1<<0) /* SW reset */
|
||||
#define UCR3_DTREN (1<<13) /* DTR interrupt enable */
|
||||
#define UCR3_PARERREN (1<<12) /* Parity enable */
|
||||
#define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */
|
||||
#define UCR3_DSR (1<<10) /* Data set ready */
|
||||
#define UCR3_DCD (1<<9) /* Data carrier detect */
|
||||
#define UCR3_RI (1<<8) /* Ring indicator */
|
||||
#define UCR3_TIMEOUTEN (1<<7) /* Timeout interrupt enable */
|
||||
#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */
|
||||
#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */
|
||||
#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */
|
||||
#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz */
|
||||
#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz */
|
||||
#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */
|
||||
#define UCR3_BPEN (1<<0) /* Preset registers enable */
|
||||
#define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */
|
||||
#define UCR4_INVR (1<<9) /* Inverted infrared reception */
|
||||
#define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */
|
||||
#define UCR4_WKEN (1<<7) /* Wake interrupt enable */
|
||||
#define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */
|
||||
#define UCR4_IRSC (1<<5) /* IR special case */
|
||||
#define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */
|
||||
#define UCR4_BKEN (1<<2) /* Break condition interrupt enable */
|
||||
#define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */
|
||||
#define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */
|
||||
#define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */
|
||||
#define UFCR_RFDIV (7<<7) /* Reference freq divider mask */
|
||||
#define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */
|
||||
#define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */
|
||||
#define USR1_RTSS (1<<14) /* RTS pin status */
|
||||
#define USR1_TRDY (1<<13)/* Transmitter ready interrupt/dma flag */
|
||||
#define USR1_RTSD (1<<12) /* RTS delta */
|
||||
#define USR1_ESCF (1<<11) /* Escape seq interrupt flag */
|
||||
#define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */
|
||||
#define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */
|
||||
#define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */
|
||||
#define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */
|
||||
#define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */
|
||||
#define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */
|
||||
#define USR2_ADET (1<<15) /* Auto baud rate detect complete */
|
||||
#define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */
|
||||
#define USR2_DTRF (1<<13) /* DTR edge interrupt flag */
|
||||
#define USR2_IDLE (1<<12) /* Idle condition */
|
||||
#define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */
|
||||
#define USR2_WAKE (1<<7) /* Wake */
|
||||
#define USR2_RTSF (1<<4) /* RTS edge interrupt flag */
|
||||
#define USR2_TXDC (1<<3) /* Transmitter complete */
|
||||
#define USR2_BRCD (1<<2) /* Break condition */
|
||||
#define USR2_ORE (1<<1) /* Overrun error */
|
||||
#define USR2_RDR (1<<0) /* Recv data ready */
|
||||
#define UTS_FRCPERR (1<<13) /* Force parity error */
|
||||
#define UTS_LOOP (1<<12) /* Loop tx and rx */
|
||||
#define UTS_TXEMPTY (1<<6) /* TxFIFO empty */
|
||||
#define UTS_RXEMPTY (1<<5) /* RxFIFO empty */
|
||||
#define UTS_TXFULL (1<<4) /* TxFIFO full */
|
||||
#define UTS_RXFULL (1<<3) /* RxFIFO full */
|
||||
#define UTS_SOFTRST (1<<0) /* Software reset */
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
void serial_setbrg(void)
|
||||
{
|
||||
u32 clk = mxc_get_clock(MXC_UART_CLK);
|
||||
|
||||
if (!gd->baudrate)
|
||||
gd->baudrate = CONFIG_BAUDRATE;
|
||||
__REG(UART_PHYS + UFCR) = 0x4 << 7; /* divide input clock by 2 */
|
||||
__REG(UART_PHYS + UBIR) = 0xf;
|
||||
__REG(UART_PHYS + UBMR) = clk / (2 * gd->baudrate);
|
||||
}
|
||||
|
||||
int serial_getc(void)
|
||||
{
|
||||
while (__REG(UART_PHYS + UTS) & UTS_RXEMPTY)
|
||||
;
|
||||
return __REG(UART_PHYS + URXD);
|
||||
}
|
||||
|
||||
void serial_putc(const char c)
|
||||
{
|
||||
__REG(UART_PHYS + UTXD) = c;
|
||||
|
||||
/* wait for transmitter to be ready */
|
||||
while (!(__REG(UART_PHYS + UTS) & UTS_TXEMPTY))
|
||||
;
|
||||
|
||||
/* If \n, also do \r */
|
||||
if (c == '\n')
|
||||
serial_putc('\r');
|
||||
}
|
||||
|
||||
/*
|
||||
* Test whether a character is in the RX buffer
|
||||
*/
|
||||
int serial_tstc(void)
|
||||
{
|
||||
/* If receive fifo is empty, return false */
|
||||
if (__REG(UART_PHYS + UTS) & UTS_RXEMPTY)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void serial_puts(const char *s)
|
||||
{
|
||||
while (*s)
|
||||
serial_putc(*s++);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise the serial port with the given baudrate. The settings
|
||||
* are always 8 data bits, no parity, 1 stop bit, no start bits.
|
||||
*
|
||||
*/
|
||||
int serial_init(void)
|
||||
{
|
||||
__REG(UART_PHYS + UCR1) = 0x0;
|
||||
__REG(UART_PHYS + UCR2) = 0x0;
|
||||
|
||||
while (!(__REG(UART_PHYS + UCR2) & UCR2_SRST))
|
||||
;
|
||||
|
||||
__REG(UART_PHYS + UCR3) = 0x0704;
|
||||
__REG(UART_PHYS + UCR4) = 0x8000;
|
||||
__REG(UART_PHYS + UESC) = 0x002b;
|
||||
__REG(UART_PHYS + UTIM) = 0x0;
|
||||
|
||||
__REG(UART_PHYS + UTS) = 0x0;
|
||||
|
||||
serial_setbrg();
|
||||
|
||||
__REG(UART_PHYS + UCR2) =
|
||||
UCR2_WS | UCR2_IRTS | UCR2_RXEN | UCR2_TXEN | UCR2_SRST;
|
||||
|
||||
__REG(UART_PHYS + UCR1) = UCR1_UARTEN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MX35 */
|
||||
@ -30,8 +30,14 @@
|
||||
|
||||
#include <config.h>
|
||||
#include <version.h>
|
||||
|
||||
.section ".text.head", "ax"
|
||||
.globl _start
|
||||
_start: b reset
|
||||
_start:
|
||||
.section ".text.vect", "ax"
|
||||
.global _start_vect
|
||||
_start_vect:
|
||||
b reset
|
||||
#ifdef CONFIG_ONENAND_IPL
|
||||
ldr pc, _hang
|
||||
ldr pc, _hang
|
||||
@ -85,6 +91,86 @@ _end_vect:
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* the actual reset code
|
||||
*/
|
||||
|
||||
.section ".text.head", "ax"
|
||||
.globl reset
|
||||
reset:
|
||||
/*
|
||||
* set the cpu to SVC32 mode
|
||||
*/
|
||||
mrs r0,cpsr
|
||||
bic r0,r0,#0x1f
|
||||
orr r0,r0,#0xd3
|
||||
msr cpsr,r0
|
||||
|
||||
#ifdef CONFIG_OMAP2420H4
|
||||
/* Copy vectors to mask ROM indirect addr */
|
||||
adr r0, _start /* r0 <- current position of code */
|
||||
add r0, r0, #4 /* skip reset vector */
|
||||
mov r2, #64 /* r2 <- size to copy */
|
||||
add r2, r0, r2 /* r2 <- source end address */
|
||||
mov r1, #SRAM_OFFSET0 /* build vect addr */
|
||||
mov r3, #SRAM_OFFSET1
|
||||
add r1, r1, r3
|
||||
mov r3, #SRAM_OFFSET2
|
||||
add r1, r1, r3
|
||||
next:
|
||||
ldmia r0!, {r3-r10} /* copy from source address [r0] */
|
||||
stmia r1!, {r3-r10} /* copy to target address [r1] */
|
||||
cmp r0, r2 /* until source end address [r2] */
|
||||
bne next /* loop until equal */
|
||||
bl cpy_clk_code /* put dpll adjust code behind vectors */
|
||||
#endif
|
||||
/* the mask ROM code should have PLL and others stable */
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
bl cpu_init_crit
|
||||
#endif
|
||||
b setup_env
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* CPU_init_critical registers
|
||||
*
|
||||
* setup important registers
|
||||
* setup memory timing
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
cpu_init_crit:
|
||||
/*
|
||||
* flush v4 I/D caches
|
||||
*/
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
|
||||
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
|
||||
|
||||
/*
|
||||
* disable MMU stuff and caches
|
||||
*/
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
|
||||
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
|
||||
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
|
||||
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
/*
|
||||
* Jump to board specific initialization... The Mask ROM will have already initialized
|
||||
* basic memory. Go here to bump up clock rate and handle wake up conditions.
|
||||
*/
|
||||
mov ip, lr /* persevere link reg across call */
|
||||
bl lowlevel_init /* go setup pll,mux,memory */
|
||||
mov lr, ip /* restore link */
|
||||
mov pc, lr /* back to my caller */
|
||||
|
||||
|
||||
.section ".text.setup", "ax"
|
||||
|
||||
.globl _TEXT_BASE
|
||||
_TEXT_BASE:
|
||||
.word TEXT_BASE
|
||||
|
||||
@ -115,51 +201,20 @@ FIQ_STACK_START:
|
||||
.word 0x0badc0de
|
||||
#endif
|
||||
|
||||
/*
|
||||
* the actual reset code
|
||||
*/
|
||||
|
||||
reset:
|
||||
/*
|
||||
* set the cpu to SVC32 mode
|
||||
*/
|
||||
mrs r0,cpsr
|
||||
bic r0,r0,#0x1f
|
||||
orr r0,r0,#0xd3
|
||||
msr cpsr,r0
|
||||
|
||||
#ifdef CONFIG_OMAP2420H4
|
||||
/* Copy vectors to mask ROM indirect addr */
|
||||
adr r0, _start /* r0 <- current position of code */
|
||||
add r0, r0, #4 /* skip reset vector */
|
||||
mov r2, #64 /* r2 <- size to copy */
|
||||
add r2, r0, r2 /* r2 <- source end address */
|
||||
mov r1, #SRAM_OFFSET0 /* build vect addr */
|
||||
mov r3, #SRAM_OFFSET1
|
||||
add r1, r1, r3
|
||||
mov r3, #SRAM_OFFSET2
|
||||
add r1, r1, r3
|
||||
next:
|
||||
ldmia r0!, {r3-r10} /* copy from source address [r0] */
|
||||
stmia r1!, {r3-r10} /* copy to target address [r1] */
|
||||
cmp r0, r2 /* until source end address [r2] */
|
||||
bne next /* loop until equal */
|
||||
bl cpy_clk_code /* put dpll adjust code behind vectors */
|
||||
#endif
|
||||
/* the mask ROM code should have PLL and others stable */
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
bl cpu_init_crit
|
||||
#endif
|
||||
setup_env:
|
||||
|
||||
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
|
||||
relocate: /* relocate U-Boot to RAM */
|
||||
adr r0, _start /* r0 <- current position of code */
|
||||
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
|
||||
adr r0, _armboot_start
|
||||
ldr r1, =_armboot_start
|
||||
cmp r0, r1 /* don't reloc during debug */
|
||||
#ifndef CONFIG_ONENAND_IPL
|
||||
beq stack_setup
|
||||
#endif /* CONFIG_ONENAND_IPL */
|
||||
|
||||
ldr r2, _TEXT_BASE
|
||||
sub r0, r1, r0
|
||||
sub r0, r2, r0
|
||||
ldr r1, _TEXT_BASE
|
||||
ldr r2, _armboot_start
|
||||
ldr r3, _bss_start
|
||||
sub r2, r3, r2 /* r2 <- size of armboot */
|
||||
@ -206,44 +261,6 @@ _start_armboot: .word start_oneboot
|
||||
_start_armboot: .word start_armboot
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* CPU_init_critical registers
|
||||
*
|
||||
* setup important registers
|
||||
* setup memory timing
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
cpu_init_crit:
|
||||
/*
|
||||
* flush v4 I/D caches
|
||||
*/
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
|
||||
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
|
||||
|
||||
/*
|
||||
* disable MMU stuff and caches
|
||||
*/
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
|
||||
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
|
||||
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
|
||||
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
/*
|
||||
* Jump to board specific initialization... The Mask ROM will have already initialized
|
||||
* basic memory. Go here to bump up clock rate and handle wake up conditions.
|
||||
*/
|
||||
mov ip, lr /* persevere link reg across call */
|
||||
bl lowlevel_init /* go setup pll,mux,memory */
|
||||
mov lr, ip /* restore link */
|
||||
mov pc, lr /* back to my caller */
|
||||
|
||||
#ifndef CONFIG_ONENAND_IPL
|
||||
/*
|
||||
*************************************************************************
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
#include <common.h>
|
||||
#include <arm926ejs.h>
|
||||
|
||||
#ifdef CONFIG_INTEGRATOR
|
||||
#if defined(CONFIG_INTEGRATOR) || defined(CONFIG_MX25)
|
||||
|
||||
/* Timer functionality supplied by Integrator board (AP or CP) */
|
||||
|
||||
|
||||
45
cpu/arm926ejs/mx25/Makefile
Normal file
45
cpu/arm926ejs/mx25/Makefile
Normal file
@ -0,0 +1,45 @@
|
||||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@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 = interrupts.o serial.o generic.o iomux.o gpio.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
|
||||
|
||||
#########################################################################
|
||||
116
cpu/arm926ejs/mx25/generic.c
Normal file
116
cpu/arm926ejs/mx25/generic.c
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* (C) Copyright 2007
|
||||
* Sascha Hauer, Pengutronix
|
||||
*
|
||||
* (C) Copyright 2009 Freescale Semiconductor
|
||||
*
|
||||
* 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 <common.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/arch/mx25-regs.h>
|
||||
|
||||
static u32 mx25_decode_pll(u32 reg)
|
||||
{
|
||||
u32 mfi = (reg >> 10) & 0xf;
|
||||
u32 mfn = reg & 0x3ff;
|
||||
u32 mfd = (reg >> 16) & 0x3ff;
|
||||
u32 pd = (reg >> 26) & 0xf;
|
||||
|
||||
u32 ref_clk = PLL_REF_CLK;
|
||||
|
||||
mfi = mfi <= 5 ? 5 : mfi;
|
||||
mfd += 1;
|
||||
pd += 1;
|
||||
|
||||
return ((2 * (ref_clk >> 10) * (mfi * mfd + mfn)) /
|
||||
(mfd * pd)) << 10;
|
||||
}
|
||||
|
||||
static u32 mx25_get_mcu_main_clk(void)
|
||||
{
|
||||
u32 cctl = __REG(CCM_CCTL);
|
||||
u32 ret_val = mx25_decode_pll(__REG(CCM_MPCTL));
|
||||
|
||||
if (cctl & CRM_CCTL_ARM_SRC) {
|
||||
ret_val *= 3;
|
||||
ret_val /= 4;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static u32 mx25_get_ahb_clk(void)
|
||||
{
|
||||
u32 cctl = __REG(CCM_CCTL);
|
||||
u32 ahb_div = ((cctl >> CRM_CCTL_AHB_OFFSET) & 3) + 1;
|
||||
|
||||
return mx25_get_mcu_main_clk()/ahb_div;
|
||||
}
|
||||
|
||||
unsigned int mx25_get_ipg_clk(void)
|
||||
{
|
||||
return mx25_get_ahb_clk()/2;
|
||||
}
|
||||
|
||||
void mx25_dump_clocks(void)
|
||||
{
|
||||
u32 cpufreq = mx25_get_mcu_main_clk();
|
||||
printf("mx25 cpu clock: %dMHz\n", cpufreq / 1000000);
|
||||
printf("ipg clock : %dHz\n", mx25_get_ipg_clk());
|
||||
}
|
||||
|
||||
unsigned int mxc_get_clock(enum mxc_clock clk)
|
||||
{
|
||||
switch (clk) {
|
||||
case MXC_ARM_CLK:
|
||||
return mx25_get_mcu_main_clk();
|
||||
case MXC_AHB_CLK:
|
||||
return mx25_get_ahb_clk();
|
||||
break;
|
||||
case MXC_IPG_PERCLK:
|
||||
case MXC_IPG_CLK:
|
||||
return mx25_get_ipg_clk();
|
||||
case MXC_UART_CLK:
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DISPLAY_CPUINFO)
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
printf("CPU: Freescale i.MX25 at %d MHz\n",
|
||||
mx25_get_mcu_main_clk() / 1000000);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Initializes on-chip ethernet controllers.
|
||||
* to override, implement board_eth_init()
|
||||
*/
|
||||
int cpu_eth_init(bd_t *bis)
|
||||
{
|
||||
int rc = -ENODEV;
|
||||
#if defined(CONFIG_MXC_FEC)
|
||||
rc = mxc_fec_initialize(bis);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
113
cpu/arm926ejs/mx25/gpio.c
Normal file
113
cpu/arm926ejs/mx25/gpio.c
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* (c) Copyright 2009 Freescale Semiconductors
|
||||
*
|
||||
* 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 <common.h>
|
||||
#include <asm/arch/mx25.h>
|
||||
#include <asm/arch/mx25_pins.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
enum gpio_reg {
|
||||
DR = 0x00,
|
||||
GDIR = 0x04,
|
||||
PSR = 0x08,
|
||||
ICR1 = 0x0C,
|
||||
ICR2 = 0x10,
|
||||
IMR = 0x14,
|
||||
ISR = 0x18,
|
||||
};
|
||||
|
||||
struct gpio_port_addr {
|
||||
int num;
|
||||
int base;
|
||||
};
|
||||
|
||||
struct gpio_port_addr gpio_port[4] = {
|
||||
{0, GPIO1_BASE},
|
||||
{1, GPIO2_BASE},
|
||||
{2, GPIO3_BASE},
|
||||
{3, GPIO4_BASE}
|
||||
};
|
||||
|
||||
/*
|
||||
* Set a GPIO pin's direction
|
||||
* @param port pointer to a gpio_port
|
||||
* @param index gpio pin index value (0~31)
|
||||
* @param is_input 0 for output; non-zero for input
|
||||
*/
|
||||
static void _set_gpio_direction(u32 port, u32 index, int is_input)
|
||||
{
|
||||
u32 reg = gpio_port[port].base + GDIR;
|
||||
u32 l;
|
||||
|
||||
l = __REG(reg);
|
||||
if (is_input)
|
||||
l &= ~(1 << index);
|
||||
else
|
||||
l |= 1 << index;
|
||||
__REG(reg) = l;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Exported function to set a GPIO pin's direction
|
||||
* @param pin a name defined by \b iomux_pin_name_t
|
||||
* @param is_input 1 (or non-zero) for input; 0 for output
|
||||
*/
|
||||
void mxc_set_gpio_direction(iomux_pin_name_t pin, int is_input)
|
||||
{
|
||||
u32 port;
|
||||
u32 gpio = IOMUX_TO_GPIO(pin);
|
||||
|
||||
port = GPIO_TO_PORT(gpio);
|
||||
_set_gpio_direction(port, GPIO_TO_INDEX(gpio), is_input);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a GPIO pin's data output
|
||||
* @param port number of gpio port
|
||||
* @param index gpio pin index value (0~31)
|
||||
* @param data value to be set (only 0 or 1 is valid)
|
||||
*/
|
||||
static void _set_gpio_dataout(u32 port, u32 index, u32 data)
|
||||
{
|
||||
u32 reg = gpio_port[port].base + DR;
|
||||
u32 l = 0;
|
||||
|
||||
l = (__REG(reg) & (~(1 << index))) | (data << index);
|
||||
__REG(reg) = l;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Exported function to set a GPIO pin's data output
|
||||
* @param pin a name defined by \b iomux_pin_name_t
|
||||
* @param data value to be set (only 0 or 1 is valid)
|
||||
*/
|
||||
|
||||
void mxc_set_gpio_dataout(iomux_pin_name_t pin, u32 data)
|
||||
{
|
||||
u32 port;
|
||||
u32 gpio = IOMUX_TO_GPIO(pin);
|
||||
|
||||
port = GPIO_TO_PORT(gpio);
|
||||
_set_gpio_dataout(port, GPIO_TO_INDEX(gpio), (data == 0) ? 0 : 1);
|
||||
}
|
||||
|
||||
121
cpu/arm926ejs/mx25/interrupts.c
Normal file
121
cpu/arm926ejs/mx25/interrupts.c
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* (C) Copyright 2007
|
||||
* Sascha Hauer, Pengutronix
|
||||
*
|
||||
* (C) Copyright 2009 Freescale Semiconductor
|
||||
*
|
||||
* 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 <common.h>
|
||||
#include <asm/arch/mx25-regs.h>
|
||||
|
||||
#define TIMER_BASE 0x53f90000 /* General purpose timer 1 */
|
||||
|
||||
/* General purpose timers registers */
|
||||
#define GPTCR __REG(TIMER_BASE) /* Control register */
|
||||
#define GPTPR __REG(TIMER_BASE + 0x4) /* Prescaler register */
|
||||
#define GPTSR __REG(TIMER_BASE + 0x8) /* Status register */
|
||||
#define GPTCNT __REG(TIMER_BASE + 0x24) /* Counter register */
|
||||
|
||||
/* General purpose timers bitfields */
|
||||
#define GPTCR_SWR (1<<15) /* Software reset */
|
||||
#define GPTCR_FRR (1<<9) /* Freerun / restart */
|
||||
#define GPTCR_CLKSOURCE_32 (4<<6) /* Clock source */
|
||||
#define GPTCR_TEN (1) /* Timer enable */
|
||||
|
||||
static ulong timestamp;
|
||||
static ulong lastinc;
|
||||
|
||||
/* nothing really to do with interrupts, just starts up a counter. */
|
||||
int interrupt_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* setup GP Timer 1 */
|
||||
GPTCR = GPTCR_SWR;
|
||||
for (i = 0; i < 100; i++)
|
||||
GPTCR = 0; /* We have no udelay by now */
|
||||
GPTPR = 0; /* 32Khz */
|
||||
GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN; /* Freerun Mode, PERCLK1 in */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void reset_timer_masked(void)
|
||||
{
|
||||
/* reset time */
|
||||
lastinc = GPTCNT; /* capture current incrementer value time */
|
||||
timestamp = 0; /* start "advancing" time stamp from 0 */
|
||||
}
|
||||
|
||||
void reset_timer(void)
|
||||
{
|
||||
reset_timer_masked();
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
ulong now = GPTCNT; /* current tick value */
|
||||
|
||||
if (now >= lastinc) /* normal mode (non roll) */
|
||||
/* move stamp forward with absolut diff ticks */
|
||||
timestamp += (now - lastinc);
|
||||
else /* we have rollover of incrementer */
|
||||
timestamp += (0xFFFFFFFF - lastinc) + now;
|
||||
lastinc = now;
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return get_timer_masked() - base;
|
||||
}
|
||||
|
||||
void set_timer(ulong t)
|
||||
{
|
||||
}
|
||||
|
||||
/* delay x useconds AND perserve advance timstamp value */
|
||||
void udelay(unsigned long usec)
|
||||
{
|
||||
ulong tmo, tmp;
|
||||
|
||||
if (usec >= 1000) { /* if "big" number, spread normalize to secs */
|
||||
tmo = usec / 1000; /* normalize usec to ticks per sec */
|
||||
tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait */
|
||||
tmo /= 1000; /* finish normalize. */
|
||||
} else { /* don't kill prior to HZ multiply */
|
||||
tmo = usec * CONFIG_SYS_HZ;
|
||||
tmo /= (1000*1000);
|
||||
}
|
||||
|
||||
tmp = get_timer(0); /* get current timestamp */
|
||||
if ((tmo + tmp + 1) < tmp) /* if overflow time stamp */
|
||||
reset_timer_masked(); /* reset "advancing" timestamp to 0 */
|
||||
else
|
||||
tmo += tmp; /* else, set stamp wake up time */
|
||||
while (get_timer_masked() < tmo)/* loop till event */
|
||||
/*NOP*/;
|
||||
}
|
||||
|
||||
void reset_cpu(ulong addr)
|
||||
{
|
||||
__REG16(WDOG_BASE) = 4;
|
||||
}
|
||||
153
cpu/arm926ejs/mx25/iomux.c
Normal file
153
cpu/arm926ejs/mx25/iomux.c
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @defgroup GPIO_MX25 Board GPIO and Muxing Setup
|
||||
* @ingroup MSL_MX25
|
||||
*/
|
||||
/*!
|
||||
* @file mach-mx25/iomux.c
|
||||
*
|
||||
* @brief I/O Muxing control functions
|
||||
*
|
||||
* @ingroup GPIO_MX25
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/mx25.h>
|
||||
#include <asm/arch/mx25_pins.h>
|
||||
#include <asm/arch/iomux.h>
|
||||
|
||||
/*!
|
||||
* IOMUX register (base) addresses
|
||||
*/
|
||||
enum iomux_reg_addr {
|
||||
IOMUXGPR = IOMUXC_BASE,
|
||||
/*!< General purpose */
|
||||
IOMUXSW_MUX_CTL = IOMUXC_BASE + 0x008,
|
||||
/*!< MUX control */
|
||||
IOMUXSW_MUX_END = IOMUXC_BASE + 0x228,
|
||||
/*!< last MUX control register */
|
||||
IOMUXSW_PAD_CTL = IOMUXC_BASE + 0x22C,
|
||||
/*!< Pad control */
|
||||
IOMUXSW_PAD_END = IOMUXC_BASE + 0x414,
|
||||
/*!< last Pad control register */
|
||||
IOMUXSW_INPUT_CTL = IOMUXC_BASE + 0x460,
|
||||
/*!< input select register */
|
||||
IOMUXSW_INPUT_END = IOMUXC_BASE + 0x580,
|
||||
/*!< last input select register */
|
||||
};
|
||||
|
||||
#define MUX_PIN_NUM_MAX \
|
||||
(((IOMUXSW_MUX_END - IOMUXSW_MUX_CTL) >> 2) + 1)
|
||||
#define MUX_INPUT_NUM_MUX \
|
||||
(((IOMUXSW_INPUT_END - IOMUXSW_INPUT_CTL) >> 2) + 1)
|
||||
|
||||
#define PIN_TO_IOMUX_INDEX(pin) (PIN_TO_IOMUX_MUX(pin) >> 2)
|
||||
|
||||
#define MUX_USED 0x80
|
||||
|
||||
/*!
|
||||
* This function is used to configure a pin through the IOMUX module.
|
||||
* FIXED ME: for backward compatible. Will be static function!
|
||||
* @param pin a pin number as defined in \b #iomux_pin_name_t
|
||||
* @param cfg an output function as defined in \b #iomux_pin_cfg_t
|
||||
*
|
||||
* @return 0 if successful; Non-zero otherwise
|
||||
*/
|
||||
static int iomux_config_mux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
|
||||
{
|
||||
u32 mux_reg = PIN_TO_IOMUX_MUX(pin);
|
||||
|
||||
if (mux_reg != NON_MUX_I) {
|
||||
mux_reg += IOMUXGPR;
|
||||
__REG(mux_reg) = cfg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Request ownership for an IO pin. This function has to be the first one
|
||||
* being called before that pin is used. The caller has to check the
|
||||
* return value to make sure it returns 0.
|
||||
*
|
||||
* @param pin a name defined by \b iomux_pin_name_t
|
||||
* @param cfg an input function as defined in \b #iomux_pin_cfg_t
|
||||
*
|
||||
* @return 0 if successful; Non-zero otherwise
|
||||
*/
|
||||
int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
|
||||
{
|
||||
int ret = iomux_config_mux(pin, cfg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Release ownership for an IO pin
|
||||
*
|
||||
* @param pin a name defined by \b iomux_pin_name_t
|
||||
* @param cfg an input function as defined in \b #iomux_pin_cfg_t
|
||||
*/
|
||||
void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function configures the pad value for a IOMUX pin.
|
||||
*
|
||||
* @param pin a pin number as defined in \b #iomux_pin_name_t
|
||||
* @param config the ORed value of elements defined in \b #iomux_pad_config_t
|
||||
*/
|
||||
void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config)
|
||||
{
|
||||
u32 pad_reg = IOMUXGPR + PIN_TO_IOMUX_PAD(pin);
|
||||
|
||||
__REG(pad_reg) = config;
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function enables/disables the general purpose function for a particular
|
||||
* signal.
|
||||
*
|
||||
* @param gp one signal as defined in \b #iomux_gp_func_t
|
||||
* @param en \b #true to enable; \b #false to disable
|
||||
*/
|
||||
void mxc_iomux_set_gpr(iomux_gp_func_t gp, int en)
|
||||
{
|
||||
u32 l;
|
||||
|
||||
l = __REG(IOMUXGPR);
|
||||
if (en)
|
||||
l |= gp;
|
||||
else
|
||||
l &= ~gp;
|
||||
|
||||
__REG(IOMUXGPR) = l;
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function configures input path.
|
||||
*
|
||||
* @param input index of input select register as defined in \b
|
||||
* #iomux_input_select_t
|
||||
* @param config the binary value of elements defined in \b
|
||||
* #iomux_input_config_t
|
||||
*/
|
||||
void mxc_iomux_set_input(iomux_input_select_t input, u32 config)
|
||||
{
|
||||
u32 reg = IOMUXSW_INPUT_CTL + (input << 2);
|
||||
|
||||
__REG(reg) = config;
|
||||
}
|
||||
|
||||
231
cpu/arm926ejs/mx25/serial.c
Normal file
231
cpu/arm926ejs/mx25/serial.c
Normal file
@ -0,0 +1,231 @@
|
||||
/*
|
||||
* (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>
|
||||
*
|
||||
* (C) Copyright 2009 Freescale Semiconductor
|
||||
*
|
||||
* 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>
|
||||
|
||||
#if defined CONFIG_MX25_UART
|
||||
|
||||
#include <asm/arch/mx25.h>
|
||||
|
||||
#define __REG(x) (*((volatile u32 *)(x)))
|
||||
|
||||
#ifdef CONFIG_MX25_UART1
|
||||
#define UART_PHYS 0x43f90000
|
||||
#else
|
||||
#error "define CONFIG_MX25_UARTx to use the mx25 UART driver"
|
||||
#endif
|
||||
|
||||
/* Register definitions */
|
||||
#define URXD 0x0 /* Receiver Register */
|
||||
#define UTXD 0x40 /* Transmitter Register */
|
||||
#define UCR1 0x80 /* Control Register 1 */
|
||||
#define UCR2 0x84 /* Control Register 2 */
|
||||
#define UCR3 0x88 /* Control Register 3 */
|
||||
#define UCR4 0x8c /* Control Register 4 */
|
||||
#define UFCR 0x90 /* FIFO Control Register */
|
||||
#define USR1 0x94 /* Status Register 1 */
|
||||
#define USR2 0x98 /* Status Register 2 */
|
||||
#define UESC 0x9c /* Escape Character Register */
|
||||
#define UTIM 0xa0 /* Escape Timer Register */
|
||||
#define UBIR 0xa4 /* BRM Incremental Register */
|
||||
#define UBMR 0xa8 /* BRM Modulator Register */
|
||||
#define UBRC 0xac /* Baud Rate Count Register */
|
||||
#define UTS 0xb4 /* UART Test Register (mx25) */
|
||||
|
||||
/* UART Control Register Bit Fields.*/
|
||||
#define URXD_CHARRDY (1<<15)
|
||||
#define URXD_ERR (1<<14)
|
||||
#define URXD_OVRRUN (1<<13)
|
||||
#define URXD_FRMERR (1<<12)
|
||||
#define URXD_BRK (1<<11)
|
||||
#define URXD_PRERR (1<<10)
|
||||
#define URXD_RX_DATA (0xFF)
|
||||
#define UCR1_ADEN (1<<15) /* Auto dectect interrupt */
|
||||
#define UCR1_ADBR (1<<14) /* Auto detect baud rate */
|
||||
#define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */
|
||||
#define UCR1_IDEN (1<<12) /* Idle condition interrupt */
|
||||
#define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */
|
||||
#define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */
|
||||
#define UCR1_IREN (1<<7) /* Infrared interface enable */
|
||||
#define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */
|
||||
#define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */
|
||||
#define UCR1_SNDBRK (1<<4) /* Send break */
|
||||
#define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */
|
||||
#define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */
|
||||
#define UCR1_DOZE (1<<1) /* Doze */
|
||||
#define UCR1_UARTEN (1<<0) /* UART enabled */
|
||||
#define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */
|
||||
#define UCR2_IRTS (1<<14) /* Ignore RTS pin */
|
||||
#define UCR2_CTSC (1<<13) /* CTS pin control */
|
||||
#define UCR2_CTS (1<<12) /* Clear to send */
|
||||
#define UCR2_ESCEN (1<<11) /* Escape enable */
|
||||
#define UCR2_PREN (1<<8) /* Parity enable */
|
||||
#define UCR2_PROE (1<<7) /* Parity odd/even */
|
||||
#define UCR2_STPB (1<<6) /* Stop */
|
||||
#define UCR2_WS (1<<5) /* Word size */
|
||||
#define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */
|
||||
#define UCR2_TXEN (1<<2) /* Transmitter enabled */
|
||||
#define UCR2_RXEN (1<<1) /* Receiver enabled */
|
||||
#define UCR2_SRST (1<<0) /* SW reset */
|
||||
#define UCR3_DTREN (1<<13) /* DTR interrupt enable */
|
||||
#define UCR3_PARERREN (1<<12) /* Parity enable */
|
||||
#define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */
|
||||
#define UCR3_DSR (1<<10) /* Data set ready */
|
||||
#define UCR3_DCD (1<<9) /* Data carrier detect */
|
||||
#define UCR3_RI (1<<8) /* Ring indicator */
|
||||
#define UCR3_TIMEOUTEN (1<<7) /* Timeout interrupt enable */
|
||||
#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */
|
||||
#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */
|
||||
#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */
|
||||
#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz */
|
||||
#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz */
|
||||
#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */
|
||||
#define UCR3_BPEN (1<<0) /* Preset registers enable */
|
||||
#define UCR4_CTSTL_32 (32<<10)/* CTS trigger level (32 chars) */
|
||||
#define UCR4_INVR (1<<9) /* Inverted infrared reception */
|
||||
#define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */
|
||||
#define UCR4_WKEN (1<<7) /* Wake interrupt enable */
|
||||
#define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */
|
||||
#define UCR4_IRSC (1<<5) /* IR special case */
|
||||
#define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */
|
||||
#define UCR4_BKEN (1<<2) /* Break condition interrupt enable */
|
||||
#define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */
|
||||
#define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */
|
||||
#define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */
|
||||
#define UFCR_RFDIV (7<<7) /* Reference freq divider mask */
|
||||
#define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */
|
||||
#define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */
|
||||
#define USR1_RTSS (1<<14) /* RTS pin status */
|
||||
#define USR1_TRDY (1<<13) /* Transmitter ready interrupt/dma flag */
|
||||
#define USR1_RTSD (1<<12) /* RTS delta */
|
||||
#define USR1_ESCF (1<<11) /* Escape seq interrupt flag */
|
||||
#define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */
|
||||
#define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */
|
||||
#define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */
|
||||
#define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */
|
||||
#define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */
|
||||
#define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */
|
||||
#define USR2_ADET (1<<15) /* Auto baud rate detect complete */
|
||||
#define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */
|
||||
#define USR2_DTRF (1<<13) /* DTR edge interrupt flag */
|
||||
#define USR2_IDLE (1<<12) /* Idle condition */
|
||||
#define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */
|
||||
#define USR2_WAKE (1<<7) /* Wake */
|
||||
#define USR2_RTSF (1<<4) /* RTS edge interrupt flag */
|
||||
#define USR2_TXDC (1<<3) /* Transmitter complete */
|
||||
#define USR2_BRCD (1<<2) /* Break condition */
|
||||
#define USR2_ORE (1<<1) /* Overrun error */
|
||||
#define USR2_RDR (1<<0) /* Recv data ready */
|
||||
#define UTS_FRCPERR (1<<13) /* Force parity error */
|
||||
#define UTS_LOOP (1<<12) /* Loop tx and rx */
|
||||
#define UTS_TXEMPTY (1<<6) /* TxFIFO empty */
|
||||
#define UTS_RXEMPTY (1<<5) /* RxFIFO empty */
|
||||
#define UTS_TXFULL (1<<4) /* TxFIFO full */
|
||||
#define UTS_RXFULL (1<<3) /* RxFIFO full */
|
||||
#define UTS_SOFTRST (1<<0) /* Software reset */
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
void serial_setbrg(void)
|
||||
{
|
||||
u32 clk = mx25_get_ipg_clk();
|
||||
|
||||
if (!gd->baudrate)
|
||||
gd->baudrate = CONFIG_BAUDRATE;
|
||||
|
||||
__REG(UART_PHYS + UFCR) = 4 << 7; /* divide input clock by 2 */
|
||||
__REG(UART_PHYS + UBIR) = 0xf;
|
||||
__REG(UART_PHYS + UBMR) = clk / (2 * gd->baudrate);
|
||||
|
||||
}
|
||||
|
||||
int serial_getc(void)
|
||||
{
|
||||
while (__REG(UART_PHYS + UTS) & UTS_RXEMPTY)
|
||||
;
|
||||
|
||||
/* mask out status from upper word */
|
||||
return (__REG(UART_PHYS + URXD) & URXD_RX_DATA)
|
||||
;
|
||||
}
|
||||
|
||||
void serial_putc(const char c)
|
||||
{
|
||||
__REG(UART_PHYS + UTXD) = c;
|
||||
|
||||
/* wait for transmitter to be ready */
|
||||
while (!(__REG(UART_PHYS + UTS) & UTS_TXEMPTY))
|
||||
;
|
||||
|
||||
/* If \n, also do \r */
|
||||
if (c == '\n')
|
||||
serial_putc('\r');
|
||||
}
|
||||
|
||||
/*
|
||||
* Test whether a character is in the RX buffer
|
||||
*/
|
||||
int serial_tstc(void)
|
||||
{
|
||||
/* If receive fifo is empty, return false */
|
||||
if (__REG(UART_PHYS + UTS) & UTS_RXEMPTY)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void serial_puts(const char *s)
|
||||
{
|
||||
while (*s)
|
||||
serial_putc(*s++);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise the serial port with the given baudrate. The settings
|
||||
* are always 8 data bits, no parity, 1 stop bit, no start bits.
|
||||
*
|
||||
*/
|
||||
int serial_init(void)
|
||||
{
|
||||
__REG(UART_PHYS + UCR1) = 0x0;
|
||||
__REG(UART_PHYS + UCR2) = 0x0;
|
||||
|
||||
while (!(__REG(UART_PHYS + UCR2) & UCR2_SRST))
|
||||
;
|
||||
|
||||
__REG(UART_PHYS + UCR3) = 0x0704;
|
||||
__REG(UART_PHYS + UCR4) = 0x8000;
|
||||
__REG(UART_PHYS + UESC) = 0x002b;
|
||||
__REG(UART_PHYS + UTIM) = 0x0;
|
||||
|
||||
__REG(UART_PHYS + UTS) = 0x0;
|
||||
|
||||
serial_setbrg();
|
||||
|
||||
__REG(UART_PHYS + UCR2) = UCR2_WS | UCR2_IRTS | UCR2_RXEN |
|
||||
UCR2_TXEN | UCR2_SRST;
|
||||
|
||||
__REG(UART_PHYS + UCR1) = UCR1_UARTEN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* CONFIG_MX25 */
|
||||
@ -125,7 +125,7 @@ FIQ_STACK_START:
|
||||
/*
|
||||
* the actual reset code
|
||||
*/
|
||||
|
||||
.globl reset
|
||||
reset:
|
||||
/*
|
||||
* set the cpu to SVC32 mode
|
||||
|
||||
47
cpu/arm926ejs/stmp378x/Makefile
Normal file
47
cpu/arm926ejs/stmp378x/Makefile
Normal file
@ -0,0 +1,47 @@
|
||||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@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 = timer.o spi.o
|
||||
SOBJS = reset.o
|
||||
|
||||
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
|
||||
START := $(addprefix $(obj),$(START))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
2
cpu/arm926ejs/stmp378x/config.mk
Normal file
2
cpu/arm926ejs/stmp378x/config.mk
Normal file
@ -0,0 +1,2 @@
|
||||
PLATFORM_CPPFLAGS += -march=armv5te
|
||||
PLATFORM_CPPFLAGS += $(call cc-option,-mtune=arm926ejs,)
|
||||
43
cpu/arm926ejs/stmp378x/reset.S
Normal file
43
cpu/arm926ejs/stmp378x/reset.S
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Processor reset for Freescale STMP378x SoC.
|
||||
*
|
||||
* Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
|
||||
*
|
||||
* -----------------------------------------------------
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
.globl reset_cpu
|
||||
reset_cpu:
|
||||
ldr r0, POWER_CHARGE
|
||||
mov r1, #0x0
|
||||
str r1, [r0]
|
||||
ldr r0, POWER_MINPWR
|
||||
str r1, [r0]
|
||||
ldr r0, CLKCTRL_RESET
|
||||
mov r1, #0x1
|
||||
str r1, [r0]
|
||||
_loop_forever:
|
||||
b _loop_forever
|
||||
|
||||
POWER_MINPWR:
|
||||
.word 0x80044020
|
||||
POWER_CHARGE:
|
||||
.word 0x80044030
|
||||
CLKCTRL_RESET:
|
||||
.word 0x80040120
|
||||
|
||||
255
cpu/arm926ejs/stmp378x/spi.c
Normal file
255
cpu/arm926ejs/stmp378x/spi.c
Normal file
@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Embedded Alley Solutions Inc.
|
||||
*
|
||||
* (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* Freescale STMP378x SSP/SPI driver
|
||||
*
|
||||
* 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 <asm/arch/spi.h>
|
||||
|
||||
#define SPI_NUM_BUSES 2
|
||||
#define SPI_NUM_SLAVES 3
|
||||
|
||||
/* Initalized in spi_init() depending on SSP port configuration */
|
||||
static unsigned long ssp_bases[SPI_NUM_BUSES];
|
||||
|
||||
/* Set in spi_set_cfg() depending on which SSP port is being used */
|
||||
static unsigned long ssp_base = SSP1_BASE;
|
||||
|
||||
/*
|
||||
* Init SSP port: SSP1 (@bus = 0) or SSP2 (@bus == 1)
|
||||
*/
|
||||
static void ssp_spi_init(unsigned int bus)
|
||||
{
|
||||
u32 spi_div;
|
||||
u32 val = 0;
|
||||
|
||||
if (bus >= SPI_NUM_BUSES) {
|
||||
printf("SPI bus %d doesn't exist\n", bus);
|
||||
return;
|
||||
}
|
||||
|
||||
ssp_base = ssp_bases[bus];
|
||||
|
||||
/* Reset block */
|
||||
|
||||
/* Clear SFTRST */
|
||||
REG_CLR(ssp_base + SSP_CTRL0, CTRL0_SFTRST);
|
||||
while (REG_RD(ssp_base + SSP_CTRL0) & CTRL0_SFTRST)
|
||||
;
|
||||
|
||||
/* Clear CLKGATE */
|
||||
REG_CLR(ssp_base + SSP_CTRL0, CTRL0_CLKGATE);
|
||||
|
||||
/* Set SFTRST and wait until CLKGATE is set */
|
||||
REG_SET(ssp_base + SSP_CTRL0, CTRL0_SFTRST);
|
||||
while (!(REG_RD(ssp_base + SSP_CTRL0) & CTRL0_CLKGATE))
|
||||
;
|
||||
|
||||
/* Clear SFTRST and CLKGATE */
|
||||
REG_CLR(ssp_base + SSP_CTRL0, CTRL0_SFTRST);
|
||||
REG_CLR(ssp_base + SSP_CTRL0, CTRL0_CLKGATE);
|
||||
|
||||
/*
|
||||
* Set CLK to desired value
|
||||
*/
|
||||
|
||||
spi_div = ((CONFIG_SSP_CLK>>1) + CONFIG_SPI_CLK - 1) / CONFIG_SPI_CLK;
|
||||
val = (2 << TIMING_CLOCK_DIVIDE) | ((spi_div - 1) << TIMING_CLOCK_RATE);
|
||||
REG_WR(ssp_base + SSP_TIMING, val);
|
||||
|
||||
/* Set transfer parameters */
|
||||
|
||||
/* Set SSP SPI Master mode and word length to 8 bit */
|
||||
REG_WR(ssp_base + SSP_CTRL1, WORD_LENGTH8 | SSP_MODE_SPI);
|
||||
|
||||
/* Set BUS_WIDTH to 1 bit and XFER_COUNT to 1 byte */
|
||||
REG_WR(ssp_base + SSP_CTRL0,
|
||||
BUS_WIDTH_SPI1 | (0x1 << CTRL0_XFER_COUNT));
|
||||
|
||||
/*
|
||||
* Set BLOCK_SIZE and BLOCK_COUNT to 0, so that XFER_COUNT
|
||||
* reflects number of bytes to send. Disalbe other bits as
|
||||
* well
|
||||
*/
|
||||
REG_WR(ssp_base + SSP_CMD0, 0x0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Init SSP ports, must be called first and only once
|
||||
*/
|
||||
void spi_init(void)
|
||||
{
|
||||
#ifdef CONFIG_SPI_SSP1
|
||||
ssp_bases[0] = SSP1_BASE;
|
||||
ssp_spi_init(0);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPI_SSP2
|
||||
ssp_bases[1] = SSP2_BASE;
|
||||
ssp_spi_init(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void spi_set_cfg(unsigned int bus, unsigned int cs, unsigned long mode)
|
||||
{
|
||||
u32 clr_mask = 0;
|
||||
u32 set_mask = 0;
|
||||
|
||||
if (bus >= SPI_NUM_BUSES || cs >= SPI_NUM_SLAVES) {
|
||||
printf("SPI device %d:%d doesn't exist", bus, cs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ssp_bases[bus] == 0) {
|
||||
printf("SSP port %d isn't in SPI mode\n", bus + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set SSP port to use */
|
||||
ssp_base = ssp_bases[bus];
|
||||
|
||||
/* Set phase and polarity: HW_SSP_CTRL1 */
|
||||
if (mode & SPI_PHASE)
|
||||
set_mask |= CTRL1_PHASE;
|
||||
else
|
||||
clr_mask |= CTRL1_PHASE;
|
||||
|
||||
if (mode & SPI_POLARITY)
|
||||
set_mask |= CTRL1_POLARITY;
|
||||
else
|
||||
clr_mask |= CTRL1_POLARITY;
|
||||
|
||||
REG_SET(ssp_base + SSP_CTRL1, set_mask);
|
||||
REG_CLR(ssp_base + SSP_CTRL1, clr_mask);
|
||||
|
||||
/* Set SSn number: HW_SSP_CTRL0 */
|
||||
REG_CLR(ssp_base + SSP_CTRL0, SPI_CS_CLR_MASK);
|
||||
|
||||
switch (cs) {
|
||||
case 0:
|
||||
set_mask = SPI_CS0;
|
||||
break;
|
||||
case 1:
|
||||
set_mask = SPI_CS1;
|
||||
break;
|
||||
case 2:
|
||||
set_mask = SPI_CS2;
|
||||
break;
|
||||
}
|
||||
|
||||
REG_SET(ssp_base + SSP_CTRL0, set_mask);
|
||||
}
|
||||
|
||||
/* Read single data byte */
|
||||
static unsigned char spi_read(void)
|
||||
{
|
||||
unsigned char b = 0;
|
||||
|
||||
/* Set XFER_LENGTH to 1 */
|
||||
REG_CLR(ssp_base + SSP_CTRL0, 0xffff);
|
||||
REG_SET(ssp_base + SSP_CTRL0, 1);
|
||||
|
||||
/* Enable READ mode */
|
||||
REG_SET(ssp_base + SSP_CTRL0, CTRL0_READ);
|
||||
|
||||
/* Set RUN bit */
|
||||
REG_SET(ssp_base + SSP_CTRL0, CTRL0_RUN);
|
||||
|
||||
|
||||
/* Set transfer */
|
||||
REG_SET(ssp_base + SSP_CTRL0, CTRL0_DATA_XFER);
|
||||
|
||||
while (REG_RD(ssp_base + SSP_STATUS) & STATUS_FIFO_EMPTY)
|
||||
;
|
||||
|
||||
/* Read data byte */
|
||||
b = REG_RD(ssp_base + SSP_DATA) & 0xff;
|
||||
|
||||
/* Wait until RUN bit is cleared */
|
||||
while (REG_RD(ssp_base + SSP_CTRL0) & CTRL0_RUN)
|
||||
;
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/* Write single data byte */
|
||||
static void spi_write(unsigned char b)
|
||||
{
|
||||
/* Set XFER_LENGTH to 1 */
|
||||
REG_CLR(ssp_base + SSP_CTRL0, 0xffff);
|
||||
REG_SET(ssp_base + SSP_CTRL0, 1);
|
||||
|
||||
/* Enable WRITE mode */
|
||||
REG_CLR(ssp_base + SSP_CTRL0, CTRL0_READ);
|
||||
|
||||
/* Set RUN bit */
|
||||
REG_SET(ssp_base + SSP_CTRL0, CTRL0_RUN);
|
||||
|
||||
/* Write data byte */
|
||||
REG_WR(ssp_base + SSP_DATA, b);
|
||||
|
||||
/* Set transfer */
|
||||
REG_SET(ssp_base + SSP_CTRL0, CTRL0_DATA_XFER);
|
||||
|
||||
/* Wait until RUN bit is cleared */
|
||||
while (REG_RD(ssp_base + SSP_CTRL0) & CTRL0_RUN)
|
||||
;
|
||||
}
|
||||
|
||||
static void spi_lock_cs(void)
|
||||
{
|
||||
REG_CLR(ssp_base + SSP_CTRL0, CTRL0_IGNORE_CRC);
|
||||
REG_SET(ssp_base + SSP_CTRL0, CTRL0_LOCK_CS);
|
||||
}
|
||||
|
||||
static void spi_unlock_cs(void)
|
||||
{
|
||||
REG_CLR(ssp_base + SSP_CTRL0, CTRL0_LOCK_CS);
|
||||
REG_SET(ssp_base + SSP_CTRL0, CTRL0_IGNORE_CRC);
|
||||
}
|
||||
|
||||
void spi_txrx(const char *dout, unsigned int tx_len, char *din,
|
||||
unsigned int rx_len, unsigned long flags)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (tx_len == 0 && rx_len == 0)
|
||||
return;
|
||||
|
||||
if (flags & SPI_START)
|
||||
spi_lock_cs();
|
||||
|
||||
for (i = 0; i < tx_len; i++) {
|
||||
|
||||
/* Check if it is last data byte to transfer */
|
||||
if (flags & SPI_STOP && rx_len == 0 && i == tx_len - 1)
|
||||
spi_unlock_cs();
|
||||
|
||||
spi_write(dout[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < rx_len; i++) {
|
||||
|
||||
/* Check if it is last data byte to transfer */
|
||||
if (flags & SPI_STOP && i == rx_len - 1)
|
||||
spi_unlock_cs();
|
||||
|
||||
din[i] = spi_read();
|
||||
}
|
||||
}
|
||||
246
cpu/arm926ejs/stmp378x/timer.c
Normal file
246
cpu/arm926ejs/stmp378x/timer.c
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Texas Instruments <www.ti.com>
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Alex Zuepke <azu@sysgo.de>
|
||||
*
|
||||
* (C) Copyright 2002-2004
|
||||
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
|
||||
*
|
||||
* (C) Copyright 2004
|
||||
* Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
|
||||
*
|
||||
* (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <common.h>
|
||||
#include <arm926ejs.h>
|
||||
#include <asm/arch/stmp378x.h>
|
||||
#include <asm/arch/timrot.h>
|
||||
|
||||
#define CONFIG_USE_TIMER0
|
||||
|
||||
#if defined(CONFIG_USE_TIMER0)
|
||||
#define TIMCTRL TIMCTRL0
|
||||
#define TIMCOUNT TIMCOUNT0
|
||||
#elif defined(CONFIG_USE_TIMER1)
|
||||
#define TIMCTRL TIMCTRL1
|
||||
#define TIMCOUNT TIMCOUNT1
|
||||
#elif defined(CONFIG_USE_TIMER2)
|
||||
#define TIMCTRL TIMCTRL2
|
||||
#define TIMCOUNT TIMCOUNT2
|
||||
#elif defined(CONFIG_USE_TIMER3)
|
||||
#define TIMCTRL TIMCTRL3
|
||||
#define TIMCOUNT TIMCOUNT3
|
||||
#else
|
||||
#error "Define which STMP378x timer to use"
|
||||
#endif
|
||||
|
||||
#define TIMER_LOAD_VAL 0x0000ffff
|
||||
|
||||
/* macro to read the 16 bit timer */
|
||||
#define READ_TIMER ((REG_RD(TIMROT_BASE + TIMCOUNT) & 0xffff0000) >> 16)
|
||||
|
||||
static ulong timestamp;
|
||||
static ulong lastdec;
|
||||
|
||||
int timer_init(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
* Reset Timers and Rotary Encoder module
|
||||
*/
|
||||
|
||||
/* Clear SFTRST */
|
||||
REG_CLR(TIMROT_BASE + ROTCTRL, 1 << 31);
|
||||
while (REG_RD(TIMROT_BASE + ROTCTRL) & (1 << 31))
|
||||
;
|
||||
|
||||
/* Clear CLKGATE */
|
||||
REG_CLR(TIMROT_BASE + ROTCTRL, 1 << 30);
|
||||
|
||||
/* Set SFTRST and wait until CLKGATE is set */
|
||||
REG_SET(TIMROT_BASE + ROTCTRL, 1 << 31);
|
||||
while (!(REG_RD(TIMROT_BASE + ROTCTRL) & (1 << 30)))
|
||||
;
|
||||
|
||||
/* Clear SFTRST and CLKGATE */
|
||||
REG_CLR(TIMROT_BASE + ROTCTRL, 1 << 31);
|
||||
REG_CLR(TIMROT_BASE + ROTCTRL, 1 << 30);
|
||||
|
||||
/*
|
||||
* Now initialize timer
|
||||
*/
|
||||
|
||||
/* Set fixed_count to 0 */
|
||||
REG_WR(TIMROT_BASE + TIMCOUNT, 0);
|
||||
|
||||
/* set UPDATE bit and 1Khz frequency */
|
||||
REG_WR(TIMROT_BASE + TIMCTRL,
|
||||
TIMCTRL_RELOAD | TIMCTRL_UPDATE | TIMCTRL_SELECT_1KHZ);
|
||||
|
||||
/* Set fixed_count to maximal value */
|
||||
REG_WR(TIMROT_BASE + TIMCOUNT, TIMER_LOAD_VAL);
|
||||
|
||||
/* init the timestamp and lastdec value */
|
||||
reset_timer_masked();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* timer without interrupts
|
||||
*/
|
||||
|
||||
void reset_timer(void)
|
||||
{
|
||||
reset_timer_masked();
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return get_timer_masked() - base;
|
||||
}
|
||||
|
||||
void set_timer(ulong t)
|
||||
{
|
||||
timestamp = t;
|
||||
}
|
||||
|
||||
/* delay x useconds AND perserve advance timstamp value */
|
||||
void udelay(unsigned long usec)
|
||||
{
|
||||
ulong tmo, tmp;
|
||||
|
||||
if (usec >= 1000) {
|
||||
/* if "big" number, spread normalization to seconds */
|
||||
tmo = usec / 1000;
|
||||
/* start to normalize for usec to ticks per sec */
|
||||
tmo *= CONFIG_SYS_HZ;
|
||||
/* find number of "ticks" to wait to achieve target */
|
||||
tmo /= 1000;
|
||||
/* finish normalize. */
|
||||
} else {
|
||||
/* else small number, don't kill it prior to HZ multiply */
|
||||
tmo = usec * CONFIG_SYS_HZ;
|
||||
tmo /= (1000*1000);
|
||||
}
|
||||
|
||||
tmp = get_timer(0);
|
||||
/* get current timestamp */
|
||||
if ((tmo + tmp + 1) < tmp)
|
||||
/* if setting this fordward will roll time stamp */
|
||||
reset_timer_masked();
|
||||
/* reset "advancing" timestamp to 0, set lastdec value */
|
||||
else
|
||||
tmo += tmp;
|
||||
/* else, set advancing stamp wake up time */
|
||||
|
||||
while (get_timer_masked() < tmo)/* loop till event */
|
||||
/*NOP*/;
|
||||
}
|
||||
|
||||
void reset_timer_masked(void)
|
||||
{
|
||||
/* reset time */
|
||||
lastdec = READ_TIMER; /* capure current decrementer value time */
|
||||
timestamp = 0; /* start "advancing" time stamp from 0 */
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
ulong now = READ_TIMER; /* current tick value */
|
||||
|
||||
if (lastdec >= now) { /* normal mode (non roll) */
|
||||
/* normal mode */
|
||||
timestamp += lastdec - now;
|
||||
/* move stamp fordward with absoulte diff ticks */
|
||||
} else {
|
||||
/* we have overflow of the count down timer */
|
||||
/* nts = ts + ld + (TLV - now)
|
||||
* ts=old stamp, ld=time that passed before passing through -1
|
||||
* (TLV-now) amount of time after passing though -1
|
||||
* nts = new "advancing time stamp"...it could also roll
|
||||
* and cause problems.
|
||||
*/
|
||||
timestamp += lastdec + TIMER_LOAD_VAL - now + 1;
|
||||
}
|
||||
lastdec = now;
|
||||
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/* waits specified delay value and resets timestamp */
|
||||
void udelay_masked(unsigned long usec)
|
||||
{
|
||||
ulong tmo;
|
||||
ulong endtime;
|
||||
signed long diff;
|
||||
|
||||
if (usec >= 1000) {
|
||||
/* if "big" number, spread normalization to seconds */
|
||||
tmo = usec / 1000;
|
||||
/* start to normalize for usec to ticks per sec */
|
||||
tmo *= CONFIG_SYS_HZ;
|
||||
/* find number of "ticks" to wait to achieve target */
|
||||
tmo /= 1000;
|
||||
/* finish normalize. */
|
||||
} else {
|
||||
/* else small number, don't kill it prior to HZ multiply */
|
||||
tmo = usec * CONFIG_SYS_HZ;
|
||||
tmo /= (1000*1000);
|
||||
}
|
||||
|
||||
endtime = get_timer_masked() + tmo;
|
||||
|
||||
do {
|
||||
ulong now = get_timer_masked();
|
||||
diff = endtime - now;
|
||||
} while (diff >= 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
ulong tbclk;
|
||||
|
||||
tbclk = CONFIG_SYS_HZ;
|
||||
return tbclk;
|
||||
}
|
||||
47
cpu/arm_cortexa8/Makefile
Normal file
47
cpu/arm_cortexa8/Makefile
Normal file
@ -0,0 +1,47 @@
|
||||
#
|
||||
# (C) Copyright 2000-2003
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@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$(CPU).a
|
||||
|
||||
START := start.o
|
||||
COBJS := cpu.o
|
||||
|
||||
SRCS := $(START:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
START := $(addprefix $(obj),$(START))
|
||||
|
||||
all: $(obj).depend $(START) $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
40
cpu/arm_cortexa8/config.mk
Normal file
40
cpu/arm_cortexa8/config.mk
Normal file
@ -0,0 +1,40 @@
|
||||
#
|
||||
# (C) Copyright 2002
|
||||
# Gary Jennejohn, DENX Software Engineering, <gj@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
|
||||
#
|
||||
PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
|
||||
-msoft-float
|
||||
|
||||
# Make ARMv5 to allow more compilers to work, even though its v7a.
|
||||
PLATFORM_CPPFLAGS += -march=armv5
|
||||
# =========================================================================
|
||||
#
|
||||
# Supply options according to compiler version
|
||||
#
|
||||
# =========================================================================
|
||||
ifdef CONFIG_SYS_APCS_GNU
|
||||
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
|
||||
else
|
||||
PLATFORM_CPPFLAGS +=$(call cc-option)
|
||||
endif
|
||||
PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
|
||||
PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,\
|
||||
$(call cc-option,-malignment-traps,))
|
||||
246
cpu/arm_cortexa8/cpu.c
Normal file
246
cpu/arm_cortexa8/cpu.c
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* (C) Copyright 2008 Texas Insturments
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Gary Jennejohn, DENX Software Engineering, <gj@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
|
||||
*/
|
||||
|
||||
/*
|
||||
* CPU specific code
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
|
||||
#ifndef CONFIG_MXC
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_L2_OFF
|
||||
void l2cache_disable(void);
|
||||
#endif
|
||||
|
||||
static void cache_flush(void);
|
||||
|
||||
/* read co-processor 15, register #1 (control register) */
|
||||
static unsigned long read_p15_c1(void)
|
||||
{
|
||||
unsigned long value;
|
||||
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c1, c0, 0\
|
||||
@ read control reg\n":"=r"(value)
|
||||
::"memory");
|
||||
return value;
|
||||
}
|
||||
|
||||
/* write to co-processor 15, register #1 (control register) */
|
||||
static void write_p15_c1(unsigned long value)
|
||||
{
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c1, c0, 0\
|
||||
@ write it back\n"::"r"(value)
|
||||
: "memory");
|
||||
|
||||
read_p15_c1();
|
||||
}
|
||||
|
||||
static void cp_delay(void)
|
||||
{
|
||||
/* Many OMAP regs need at least 2 nops */
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
}
|
||||
|
||||
/* See also ARM Ref. Man. */
|
||||
#define C1_MMU (1<<0) /* mmu off/on */
|
||||
#define C1_ALIGN (1<<1) /* alignment faults off/on */
|
||||
#define C1_DC (1<<2) /* dcache off/on */
|
||||
#define C1_WB (1<<3) /* merging write buffer on/off */
|
||||
#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */
|
||||
#define C1_SYS_PROT (1<<8) /* system protection */
|
||||
#define C1_ROM_PROT (1<<9) /* ROM protection */
|
||||
#define C1_IC (1<<12) /* icache off/on */
|
||||
#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */
|
||||
#define RESERVED_1 (0xf << 3) /* must be 111b for R/W */
|
||||
|
||||
int cpu_init(void)
|
||||
{
|
||||
/*
|
||||
* setup up stacks if necessary
|
||||
*/
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
IRQ_STACK_START =
|
||||
_armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4;
|
||||
FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cleanup_before_linux(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
* this function is called just before we call linux
|
||||
* it prepares the processor for linux
|
||||
*
|
||||
* we turn off caches etc ...
|
||||
*/
|
||||
disable_interrupts();
|
||||
|
||||
/* turn off I/D-cache */
|
||||
icache_disable();
|
||||
dcache_disable();
|
||||
|
||||
/* invalidate I-cache */
|
||||
cache_flush();
|
||||
|
||||
#ifndef CONFIG_L2_OFF
|
||||
/* turn off L2 cache */
|
||||
l2cache_disable();
|
||||
/* invalidate L2 cache also */
|
||||
v7_flush_dcache_all(get_device_type());
|
||||
#endif
|
||||
i = 0;
|
||||
/* mem barrier to sync up things */
|
||||
asm("mcr p15, 0, %0, c7, c10, 4": :"r"(i));
|
||||
|
||||
#ifndef CONFIG_L2_OFF
|
||||
l2cache_enable();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
disable_interrupts();
|
||||
reset_cpu(0);
|
||||
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void icache_enable(void)
|
||||
{
|
||||
ulong reg;
|
||||
|
||||
reg = read_p15_c1(); /* get control reg. */
|
||||
cp_delay();
|
||||
write_p15_c1(reg | C1_IC);
|
||||
}
|
||||
|
||||
void icache_disable(void)
|
||||
{
|
||||
ulong reg;
|
||||
|
||||
reg = read_p15_c1();
|
||||
cp_delay();
|
||||
write_p15_c1(reg & ~C1_IC);
|
||||
}
|
||||
|
||||
void dcache_disable (void)
|
||||
{
|
||||
ulong reg;
|
||||
|
||||
reg = read_p15_c1 ();
|
||||
cp_delay ();
|
||||
write_p15_c1 (reg & ~C1_DC);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_L2_OFF
|
||||
void l2cache_enable()
|
||||
{
|
||||
unsigned long i;
|
||||
volatile unsigned int j;
|
||||
|
||||
/* ES2 onwards we can disable/enable L2 ourselves */
|
||||
if (get_cpu_rev() == CPU_3430_ES2) {
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i));
|
||||
__asm__ __volatile__("orr %0, %0, #0x2":"=r"(i));
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i));
|
||||
} else {
|
||||
/* Save r0, r12 and restore them after usage */
|
||||
__asm__ __volatile__("mov %0, r12":"=r"(j));
|
||||
__asm__ __volatile__("mov %0, r0":"=r"(i));
|
||||
|
||||
/*
|
||||
* GP Device ROM code API usage here
|
||||
* r12 = AUXCR Write function and r0 value
|
||||
*/
|
||||
__asm__ __volatile__("mov r12, #0x3");
|
||||
__asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1");
|
||||
__asm__ __volatile__("orr r0, r0, #0x2");
|
||||
/* SMI instruction to call ROM Code API */
|
||||
__asm__ __volatile__(".word 0xE1600070");
|
||||
__asm__ __volatile__("mov r0, %0":"=r"(i));
|
||||
__asm__ __volatile__("mov r12, %0":"=r"(j));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void l2cache_disable()
|
||||
{
|
||||
unsigned long i;
|
||||
volatile unsigned int j;
|
||||
|
||||
/* ES2 onwards we can disable/enable L2 ourselves */
|
||||
if (get_cpu_rev() == CPU_3430_ES2) {
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i));
|
||||
__asm__ __volatile__("bic %0, %0, #0x2":"=r"(i));
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i));
|
||||
} else {
|
||||
/* Save r0, r12 and restore them after usage */
|
||||
__asm__ __volatile__("mov %0, r12":"=r"(j));
|
||||
__asm__ __volatile__("mov %0, r0":"=r"(i));
|
||||
|
||||
/*
|
||||
* GP Device ROM code API usage here
|
||||
* r12 = AUXCR Write function and r0 value
|
||||
*/
|
||||
__asm__ __volatile__("mov r12, #0x3");
|
||||
__asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1");
|
||||
__asm__ __volatile__("bic r0, r0, #0x2");
|
||||
/* SMI instruction to call ROM Code API */
|
||||
__asm__ __volatile__(".word 0xE1600070");
|
||||
__asm__ __volatile__("mov r0, %0":"=r"(i));
|
||||
__asm__ __volatile__("mov r12, %0":"=r"(j));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int icache_status(void)
|
||||
{
|
||||
return (read_p15_c1() & C1_IC) != 0;
|
||||
}
|
||||
|
||||
static void cache_flush(void)
|
||||
{
|
||||
asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
|
||||
}
|
||||
|
||||
48
cpu/arm_cortexa8/mx51/Makefile
Normal file
48
cpu/arm_cortexa8/mx51/Makefile
Normal file
@ -0,0 +1,48 @@
|
||||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
#
|
||||
# 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 = interrupts.o serial.o generic.o iomux.o
|
||||
SOBJS = mxc_nand_load.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
|
||||
|
||||
#########################################################################
|
||||
669
cpu/arm_cortexa8/mx51/crm_regs.h
Normal file
669
cpu/arm_cortexa8/mx51/crm_regs.h
Normal file
@ -0,0 +1,669 @@
|
||||
/*
|
||||
* Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
#ifndef __ARCH_ARM_MACH_MX51_CRM_REGS_H__
|
||||
#define __ARCH_ARM_MACH_MX51_CRM_REGS_H__
|
||||
|
||||
#define MXC_CCM_BASE CCM_BASE_ADDR
|
||||
#define MXC_DPLL1_BASE PLL1_BASE_ADDR
|
||||
#define MXC_DPLL2_BASE PLL2_BASE_ADDR
|
||||
#define MXC_DPLL3_BASE PLL3_BASE_ADDR
|
||||
|
||||
/* PLL Register Offsets */
|
||||
#define MXC_PLL_DP_CTL 0x00
|
||||
#define MXC_PLL_DP_CONFIG 0x04
|
||||
#define MXC_PLL_DP_OP 0x08
|
||||
#define MXC_PLL_DP_MFD 0x0C
|
||||
#define MXC_PLL_DP_MFN 0x10
|
||||
#define MXC_PLL_DP_MFNMINUS 0x14
|
||||
#define MXC_PLL_DP_MFNPLUS 0x18
|
||||
#define MXC_PLL_DP_HFS_OP 0x1C
|
||||
#define MXC_PLL_DP_HFS_MFD 0x20
|
||||
#define MXC_PLL_DP_HFS_MFN 0x24
|
||||
#define MXC_PLL_DP_MFN_TOGC 0x28
|
||||
#define MXC_PLL_DP_DESTAT 0x2c
|
||||
|
||||
/* PLL Register Bit definitions */
|
||||
#define MXC_PLL_DP_CTL_MUL_CTRL 0x2000
|
||||
#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000
|
||||
#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET 12
|
||||
#define MXC_PLL_DP_CTL_ADE 0x800
|
||||
#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400
|
||||
#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8)
|
||||
#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8
|
||||
#define MXC_PLL_DP_CTL_HFSM 0x80
|
||||
#define MXC_PLL_DP_CTL_PRE 0x40
|
||||
#define MXC_PLL_DP_CTL_UPEN 0x20
|
||||
#define MXC_PLL_DP_CTL_RST 0x10
|
||||
#define MXC_PLL_DP_CTL_RCP 0x8
|
||||
#define MXC_PLL_DP_CTL_PLM 0x4
|
||||
#define MXC_PLL_DP_CTL_BRM0 0x2
|
||||
#define MXC_PLL_DP_CTL_LRF 0x1
|
||||
|
||||
#define MXC_PLL_DP_CONFIG_BIST 0x8
|
||||
#define MXC_PLL_DP_CONFIG_SJC_CE 0x4
|
||||
#define MXC_PLL_DP_CONFIG_AREN 0x2
|
||||
#define MXC_PLL_DP_CONFIG_LDREQ 0x1
|
||||
|
||||
#define MXC_PLL_DP_OP_MFI_OFFSET 4
|
||||
#define MXC_PLL_DP_OP_MFI_MASK (0xF << 4)
|
||||
#define MXC_PLL_DP_OP_PDF_OFFSET 0
|
||||
#define MXC_PLL_DP_OP_PDF_MASK 0xF
|
||||
|
||||
#define MXC_PLL_DP_MFD_OFFSET 0
|
||||
#define MXC_PLL_DP_MFD_MASK 0x07FFFFFF
|
||||
|
||||
#define MXC_PLL_DP_MFN_OFFSET 0x0
|
||||
#define MXC_PLL_DP_MFN_MASK 0x07FFFFFF
|
||||
|
||||
#define MXC_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17)
|
||||
#define MXC_PLL_DP_MFN_TOGC_TOG_EN (1 << 16)
|
||||
#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0
|
||||
#define MXC_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF
|
||||
|
||||
#define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31)
|
||||
#define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF
|
||||
|
||||
/* Register addresses of CCM*/
|
||||
#define MXC_CCM_CCR (MXC_CCM_BASE + 0x00)
|
||||
#define MXC_CCM_CCDR (MXC_CCM_BASE + 0x04)
|
||||
#define MXC_CCM_CSR (MXC_CCM_BASE + 0x08)
|
||||
#define MXC_CCM_CCSR (MXC_CCM_BASE + 0x0C)
|
||||
#define MXC_CCM_CACRR (MXC_CCM_BASE + 0x10)
|
||||
#define MXC_CCM_CBCDR (MXC_CCM_BASE + 0x14)
|
||||
#define MXC_CCM_CBCMR (MXC_CCM_BASE + 0x18)
|
||||
#define MXC_CCM_CSCMR1 (MXC_CCM_BASE + 0x1C)
|
||||
#define MXC_CCM_CSCMR2 (MXC_CCM_BASE + 0x20)
|
||||
#define MXC_CCM_CSCDR1 (MXC_CCM_BASE + 0x24)
|
||||
#define MXC_CCM_CS1CDR (MXC_CCM_BASE + 0x28)
|
||||
#define MXC_CCM_CS2CDR (MXC_CCM_BASE + 0x2C)
|
||||
#define MXC_CCM_CDCDR (MXC_CCM_BASE + 0x30)
|
||||
#define MXC_CCM_CHSCDR (MXC_CCM_BASE + 0x34)
|
||||
#define MXC_CCM_CSCDR2 (MXC_CCM_BASE + 0x38)
|
||||
#define MXC_CCM_CSCDR3 (MXC_CCM_BASE + 0x3C)
|
||||
#define MXC_CCM_CSCDR4 (MXC_CCM_BASE + 0x40)
|
||||
#define MXC_CCM_CWDR (MXC_CCM_BASE + 0x44)
|
||||
#define MXC_CCM_CDHIPR (MXC_CCM_BASE + 0x48)
|
||||
#define MXC_CCM_CDCR (MXC_CCM_BASE + 0x4C)
|
||||
#define MXC_CCM_CTOR (MXC_CCM_BASE + 0x50)
|
||||
#define MXC_CCM_CLPCR (MXC_CCM_BASE + 0x54)
|
||||
#define MXC_CCM_CISR (MXC_CCM_BASE + 0x58)
|
||||
#define MXC_CCM_CIMR (MXC_CCM_BASE + 0x5C)
|
||||
#define MXC_CCM_CCOSR (MXC_CCM_BASE + 0x60)
|
||||
#define MXC_CCM_CGPR (MXC_CCM_BASE + 0x64)
|
||||
#define MXC_CCM_CCGR0 (MXC_CCM_BASE + 0x68)
|
||||
#define MXC_CCM_CCGR1 (MXC_CCM_BASE + 0x6C)
|
||||
#define MXC_CCM_CCGR2 (MXC_CCM_BASE + 0x70)
|
||||
#define MXC_CCM_CCGR3 (MXC_CCM_BASE + 0x74)
|
||||
#define MXC_CCM_CCGR4 (MXC_CCM_BASE + 0x78)
|
||||
#define MXC_CCM_CCGR5 (MXC_CCM_BASE + 0x7C)
|
||||
#define MXC_CCM_CCGR6 (MXC_CCM_BASE + 0x80)
|
||||
#define MXC_CCM_CMEOR (MXC_CCM_BASE + 0x84)
|
||||
|
||||
/* Define the bits in register CCR */
|
||||
#define MXC_CCM_CCR_COSC_EN (1 << 12)
|
||||
#define MXC_CCM_CCR_FPM_MULT_MASK (1 << 11)
|
||||
#define MXC_CCM_CCR_CAMP2_EN (1 << 10)
|
||||
#define MXC_CCM_CCR_CAMP1_EN (1 << 9)
|
||||
#define MXC_CCM_CCR_FPM_EN (1 << 8)
|
||||
#define MXC_CCM_CCR_OSCNT_OFFSET (0)
|
||||
#define MXC_CCM_CCR_OSCNT_MASK (0xFF)
|
||||
|
||||
/* Define the bits in register CCDR */
|
||||
#define MXC_CCM_CCDR_HSC_HS_MASK (0x1 << 18)
|
||||
#define MXC_CCM_CCDR_IPU_HS_MASK (0x1 << 17)
|
||||
#define MXC_CCM_CCDR_EMI_HS_MASK (0x1 << 16)
|
||||
|
||||
/* Define the bits in register CSR */
|
||||
#define MXC_CCM_CSR_COSR_READY (1 << 5)
|
||||
#define MXC_CCM_CSR_LVS_VALUE (1 << 4)
|
||||
#define MXC_CCM_CSR_CAMP2_READY (1 << 3)
|
||||
#define MXC_CCM_CSR_CAMP1_READY (1 << 2)
|
||||
#define MXC_CCM_CSR_FPM_READY (1 << 1)
|
||||
#define MXC_CCM_CSR_REF_EN_B (1 << 0)
|
||||
|
||||
/* Define the bits in register CCSR */
|
||||
#define MXC_CCM_CCSR_LP_APM_SEL (0x1 << 9)
|
||||
#define MXC_CCM_CCSR_STEP_SEL_OFFSET (7)
|
||||
#define MXC_CCM_CCSR_STEP_SEL_MASK (0x3 << 7)
|
||||
#define MXC_CCM_CCSR_PLL2_PODF_OFFSET (5)
|
||||
#define MXC_CCM_CCSR_PLL2_PODF_MASK (0x3 << 5)
|
||||
#define MXC_CCM_CCSR_PLL3_PODF_OFFSET (3)
|
||||
#define MXC_CCM_CCSR_PLL3_PODF_MASK (0x3 << 3)
|
||||
#define MXC_CCM_CCSR_PLL1_SW_CLK_SEL (1 << 2)
|
||||
#define MXC_CCM_CCSR_PLL2_SW_CLK_SEL (1 << 1)
|
||||
#define MXC_CCM_CCSR_PLL3_SW_CLK_SEL (1 << 0)
|
||||
|
||||
/* Define the bits in register CACRR */
|
||||
#define MXC_CCM_CACRR_ARM_PODF_OFFSET (0)
|
||||
#define MXC_CCM_CACRR_ARM_PODF_MASK (0x7)
|
||||
|
||||
/* Define the bits in register CBCDR */
|
||||
#define MXC_CCM_CBCDR_EMI_CLK_SEL (0x1 << 26)
|
||||
#define MXC_CCM_CBCDR_PERIPH_CLK_SEL (0x1 << 25)
|
||||
#define MXC_CCM_CBCDR_EMI_PODF_OFFSET (22)
|
||||
#define MXC_CCM_CBCDR_EMI_PODF_MASK (0x7 << 22)
|
||||
#define MXC_CCM_CBCDR_AXI_B_PODF_OFFSET (19)
|
||||
#define MXC_CCM_CBCDR_AXI_B_PODF_MASK (0x7 << 19)
|
||||
#define MXC_CCM_CBCDR_AXI_A_PODF_OFFSET (16)
|
||||
#define MXC_CCM_CBCDR_AXI_A_PODF_MASK (0x7 << 16)
|
||||
#define MXC_CCM_CBCDR_NFC_PODF_OFFSET (13)
|
||||
#define MXC_CCM_CBCDR_NFC_PODF_MASK (0x7 << 13)
|
||||
#define MXC_CCM_CBCDR_AHB_PODF_OFFSET (10)
|
||||
#define MXC_CCM_CBCDR_AHB_PODF_MASK (0x7 << 10)
|
||||
#define MXC_CCM_CBCDR_IPG_PODF_OFFSET (8)
|
||||
#define MXC_CCM_CBCDR_IPG_PODF_MASK (0x3 << 8)
|
||||
#define MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET (6)
|
||||
#define MXC_CCM_CBCDR_PERCLK_PRED1_MASK (0x3 << 6)
|
||||
#define MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET (3)
|
||||
#define MXC_CCM_CBCDR_PERCLK_PRED2_MASK (0x7 << 3)
|
||||
#define MXC_CCM_CBCDR_PERCLK_PODF_OFFSET (0)
|
||||
#define MXC_CCM_CBCDR_PERCLK_PODF_MASK (0x7)
|
||||
|
||||
/* Define the bits in register CBCMR */
|
||||
#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET (14)
|
||||
#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK (0x3 << 14)
|
||||
#define MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET (12)
|
||||
#define MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK (0x3 << 12)
|
||||
#define MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET (10)
|
||||
#define MXC_CCM_CBCMR_DDR_CLK_SEL_MASK (0x3 << 10)
|
||||
#define MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_OFFSET (8)
|
||||
#define MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_MASK (0x3 << 8)
|
||||
#define MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_OFFSET (6)
|
||||
#define MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_MASK (0x3 << 6)
|
||||
#define MXC_CCM_CBCMR_GPU_CLK_SEL_OFFSET (4)
|
||||
#define MXC_CCM_CBCMR_GPU_CLK_SEL_MASK (0x3 << 4)
|
||||
#define MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL (0x1 << 1)
|
||||
#define MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL (0x1 << 0)
|
||||
|
||||
/* Define the bits in register CSCMR1 */
|
||||
#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET (30)
|
||||
#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK (0x3 << 30)
|
||||
#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET (28)
|
||||
#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK (0x3 << 28)
|
||||
#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET (26)
|
||||
#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL (0x1 << 26)
|
||||
#define MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET (24)
|
||||
#define MXC_CCM_CSCMR1_UART_CLK_SEL_MASK (0x3 << 24)
|
||||
#define MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET (22)
|
||||
#define MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK (0x3 << 22)
|
||||
#define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET (20)
|
||||
#define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK (0x3 << 20)
|
||||
#define MXC_CCM_CSCMR1_ESDHC3_CLK_SEL (0x1 << 19)
|
||||
#define MXC_CCM_CSCMR1_ESDHC4_CLK_SEL (0x1 << 18)
|
||||
#define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_OFFSET (16)
|
||||
#define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_MASK (0x3 << 16)
|
||||
#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET (14)
|
||||
#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK (0x3 << 14)
|
||||
#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET (12)
|
||||
#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK (0x3 << 12)
|
||||
#define MXC_CCM_CSCMR1_SSI3_CLK_SEL (0x1 << 11)
|
||||
#define MXC_CCM_CSCMR1_VPU_RCLK_SEL (0x1 << 10)
|
||||
#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_OFFSET (8)
|
||||
#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_MASK (0x3 << 8)
|
||||
#define MXC_CCM_CSCMR1_TVE_CLK_SEL (0x1 << 7)
|
||||
#define MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL (0x1 << 6)
|
||||
#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET (4)
|
||||
#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK (0x3 << 4)
|
||||
#define MXC_CCM_CSCMR1_SPDIF_CLK_SEL_OFFSET (2)
|
||||
#define MXC_CCM_CSCMR1_SPDIF_CLK_SEL_MASK (0x3 << 2)
|
||||
#define MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL (0x1 << 1)
|
||||
#define MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL (0x1)
|
||||
|
||||
/* Define the bits in register CSCMR2 */
|
||||
#define MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET (26)
|
||||
#define MXC_CCM_CSCMR2_DI_CLK_SEL_MASK (0x7 << 26)
|
||||
#define MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_OFFSET (24)
|
||||
#define MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_MASK (0x3 << 24)
|
||||
#define MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_OFFSET (22)
|
||||
#define MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_MASK (0x3 << 22)
|
||||
#define MXC_CCM_CSCMR2_ESC_CLK_SEL_OFFSET (20)
|
||||
#define MXC_CCM_CSCMR2_ESC_CLK_SEL_MASK (0x3 << 20)
|
||||
#define MXC_CCM_CSCMR2_HSC2_CLK_SEL_OFFSET (18)
|
||||
#define MXC_CCM_CSCMR2_HSC2_CLK_SEL_MASK (0x3 << 18)
|
||||
#define MXC_CCM_CSCMR2_HSC1_CLK_SEL_OFFSET (16)
|
||||
#define MXC_CCM_CSCMR2_HSC1_CLK_SEL_MASK (0x3 << 16)
|
||||
#define MXC_CCM_CSCMR2_HSI2C_CLK_SEL_OFFSET (14)
|
||||
#define MXC_CCM_CSCMR2_HSI2C_CLK_SEL_MASK (0x3 << 14)
|
||||
#define MXC_CCM_CSCMR2_FIRI_CLK_SEL_OFFSET (12)
|
||||
#define MXC_CCM_CSCMR2_FIRI_CLK_SEL_MASK (0x3 << 12)
|
||||
#define MXC_CCM_CSCMR2_SIM_CLK_SEL_OFFSET (10)
|
||||
#define MXC_CCM_CSCMR2_SIM_CLK_SEL_MASK (0x3 << 10)
|
||||
#define MXC_CCM_CSCMR2_SLIMBUS_COM (0x1 << 9)
|
||||
#define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_OFFSET (6)
|
||||
#define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_MASK (0x7 << 6)
|
||||
#define MXC_CCM_CSCMR2_SPDIF1_COM (1 << 5)
|
||||
#define MXC_CCM_CSCMR2_SPDIF0_COM (1 << 4)
|
||||
#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_OFFSET (2)
|
||||
#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_MASK (0x3 << 2)
|
||||
#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_OFFSET (0)
|
||||
#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK (0x3)
|
||||
|
||||
/* Define the bits in register CSCDR1 */
|
||||
#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET (22)
|
||||
#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK (0x7 << 22)
|
||||
#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET (19)
|
||||
#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK (0x7 << 19)
|
||||
#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET (16)
|
||||
#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK (0x7 << 16)
|
||||
#define MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET (14)
|
||||
#define MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK (0x3 << 14)
|
||||
#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET (11)
|
||||
#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK (0x7 << 11)
|
||||
#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET (8)
|
||||
#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK (0x7 << 8)
|
||||
#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET (6)
|
||||
#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK (0x3 << 6)
|
||||
#define MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET (3)
|
||||
#define MXC_CCM_CSCDR1_UART_CLK_PRED_MASK (0x7 << 3)
|
||||
#define MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET (0)
|
||||
#define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK (0x7)
|
||||
|
||||
/* Define the bits in register CS1CDR and CS2CDR */
|
||||
#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET (22)
|
||||
#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK (0x7 << 22)
|
||||
#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET (16)
|
||||
#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK (0x3F << 16)
|
||||
#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET (6)
|
||||
#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK (0x7 << 6)
|
||||
#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET (0)
|
||||
#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK (0x3F)
|
||||
|
||||
#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_OFFSET (22)
|
||||
#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_MASK (0x7 << 22)
|
||||
#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_OFFSET (16)
|
||||
#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_MASK (0x3F << 16)
|
||||
#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET (6)
|
||||
#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK (0x7 << 6)
|
||||
#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET (0)
|
||||
#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK (0x3F)
|
||||
|
||||
/* Define the bits in register CDCDR */
|
||||
#define MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET (28)
|
||||
#define MXC_CCM_CDCDR_TVE_CLK_PRED_MASK (0x7 << 28)
|
||||
#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET (25)
|
||||
#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK (0x7 << 25)
|
||||
#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET (19)
|
||||
#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK (0x3F << 19)
|
||||
#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET (16)
|
||||
#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK (0x7 << 16)
|
||||
#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET (9)
|
||||
#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK (0x3F << 9)
|
||||
#define MXC_CCM_CDCDR_DI_CLK_PRED_OFFSET (6)
|
||||
#define MXC_CCM_CDCDR_DI_CLK_PRED_MASK (0x7 << 6)
|
||||
#define MXC_CCM_CDCDR_USB_PHY_PRED_OFFSET (3)
|
||||
#define MXC_CCM_CDCDR_USB_PHY_PRED_MASK (0x7 << 3)
|
||||
#define MXC_CCM_CDCDR_USB_PHY_PODF_OFFSET (0)
|
||||
#define MXC_CCM_CDCDR_USB_PHY_PODF_MASK (0x7)
|
||||
|
||||
/* Define the bits in register CHSCCDR */
|
||||
#define MXC_CCM_CHSCCDR_ESC_CLK_PRED_OFFSET (12)
|
||||
#define MXC_CCM_CHSCCDR_ESC_CLK_PRED_MASK (0x7 << 12)
|
||||
#define MXC_CCM_CHSCCDR_ESC_CLK_PODF_OFFSET (6)
|
||||
#define MXC_CCM_CHSCCDR_ESC_CLK_PODF_MASK (0x3F << 6)
|
||||
#define MXC_CCM_CHSCCDR_HSC2_CLK_PODF_OFFSET (3)
|
||||
#define MXC_CCM_CHSCCDR_HSC2_CLK_PODF_MASK (0x7 << 3)
|
||||
#define MXC_CCM_CHSCCDR_HSC1_CLK_PODF_OFFSET (0)
|
||||
#define MXC_CCM_CHSCCDR_HSC1_CLK_PODF_MASK (0x7)
|
||||
|
||||
/* Define the bits in register CSCDR2 */
|
||||
#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET (25)
|
||||
#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK (0x7 << 25)
|
||||
#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET (19)
|
||||
#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK (0x3F << 19)
|
||||
#define MXC_CCM_CSCDR2_SIM_CLK_PRED_OFFSET (16)
|
||||
#define MXC_CCM_CSCDR2_SIM_CLK_PRED_MASK (0x7 << 16)
|
||||
#define MXC_CCM_CSCDR2_SIM_CLK_PODF_OFFSET (9)
|
||||
#define MXC_CCM_CSCDR2_SIM_CLK_PODF_MASK (0x3F << 9)
|
||||
#define MXC_CCM_CSCDR2_SLIMBUS_CLK_PRED_OFFSET (6)
|
||||
#define MXC_CCM_CSCDR2_SLIMBUS_PRED_MASK (0x7 << 6)
|
||||
#define MXC_CCM_CSCDR2_SLIMBUS_PODF_OFFSET (0)
|
||||
#define MXC_CCM_CSCDR2_SLIMBUS_PODF_MASK (0x3F)
|
||||
|
||||
/* Define the bits in register CSCDR3 */
|
||||
#define MXC_CCM_CSCDR3_HSI2C_CLK_PRED_OFFSET (16)
|
||||
#define MXC_CCM_CSCDR3_HSI2C_CLK_PRED_MASK (0x7 << 16)
|
||||
#define MXC_CCM_CSCDR3_HSI2C_CLK_PODF_OFFSET (9)
|
||||
#define MXC_CCM_CSCDR3_HSI2C_CLK_PODF_MASK (0x3F << 9)
|
||||
#define MXC_CCM_CSCDR3_FIRI_CLK_PRED_OFFSET (6)
|
||||
#define MXC_CCM_CSCDR3_FIRI_CLK_PRED_MASK (0x7 << 6)
|
||||
#define MXC_CCM_CSCDR3_FIRI_CLK_PODF_OFFSET (0)
|
||||
#define MXC_CCM_CSCDR3_FIRI_CLK_PODF_MASK (0x3F)
|
||||
|
||||
/* Define the bits in register CSCDR4 */
|
||||
#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_OFFSET (16)
|
||||
#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_MASK (0x7 << 16)
|
||||
#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_OFFSET (9)
|
||||
#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_MASK (0x3F << 9)
|
||||
#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_OFFSET (6)
|
||||
#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_MASK (0x7 << 6)
|
||||
#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_OFFSET (0)
|
||||
#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_MASK (0x3F)
|
||||
|
||||
/* Define the bits in register CDHIPR */
|
||||
#define MXC_CCM_CDHIPR_ARM_PODF_BUSY (1 << 16)
|
||||
#define MXC_CCM_CDHIPR_EMI_CLK_SEL_BUSY (1 << 6)
|
||||
#define MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY (1 << 5)
|
||||
#define MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY (1 << 4)
|
||||
#define MXC_CCM_CDHIPR_AHB_PODF_BUSY (1 << 3)
|
||||
#define MXC_CCM_CDHIPR_EMI_PODF_BUSY (1 << 2)
|
||||
#define MXC_CCM_CDHIPR_AXI_B_PODF_BUSY (1 << 1)
|
||||
#define MXC_CCM_CDHIPR_AXI_A_PODF_BUSY (1 << 0)
|
||||
|
||||
/* Define the bits in register CDCR */
|
||||
#define MXC_CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER (0x1 << 2)
|
||||
#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_OFFSET (0)
|
||||
#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK (0x3)
|
||||
|
||||
/* Define the bits in register CLPCR */
|
||||
#define MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS (0x1 << 23)
|
||||
#define MXC_CCM_CLPCR_BYPASS_SCC_LPM_HS (0x1 << 22)
|
||||
#define MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS (0x1 << 21)
|
||||
#define MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS (0x1 << 20)
|
||||
#define MXC_CCM_CLPCR_BYPASS_EMI_LPM_HS (0x1 << 19)
|
||||
#define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS (0x1 << 18)
|
||||
#define MXC_CCM_CLPCR_BYPASS_RTIC_LPM_HS (0x1 << 17)
|
||||
#define MXC_CCM_CLPCR_BYPASS_RNGC_LPM_HS (0x1 << 16)
|
||||
#define MXC_CCM_CLPCR_COSC_PWRDOWN (0x1 << 11)
|
||||
#define MXC_CCM_CLPCR_STBY_COUNT_OFFSET (9)
|
||||
#define MXC_CCM_CLPCR_STBY_COUNT_MASK (0x3 << 9)
|
||||
#define MXC_CCM_CLPCR_VSTBY (0x1 << 8)
|
||||
#define MXC_CCM_CLPCR_DIS_REF_OSC (0x1 << 7)
|
||||
#define MXC_CCM_CLPCR_SBYOS (0x1 << 6)
|
||||
#define MXC_CCM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
|
||||
#define MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET (3)
|
||||
#define MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK (0x3 << 3)
|
||||
#define MXC_CCM_CLPCR_LPM_OFFSET (0)
|
||||
#define MXC_CCM_CLPCR_LPM_MASK (0x3)
|
||||
|
||||
/* Define the bits in register CISR */
|
||||
#define MXC_CCM_CISR_ARM_PODF_LOADED (0x1 << 25)
|
||||
#define MXC_CCM_CISR_NFC_IPG_INT_MEM_PODF_LOADED (0x1 << 21)
|
||||
#define MXC_CCM_CISR_AHB_PODF_LOADED (0x1 << 20)
|
||||
#define MXC_CCM_CISR_EMI_PODF_LOADED (0x1 << 19)
|
||||
#define MXC_CCM_CISR_AXI_B_PODF_LOADED (0x1 << 18)
|
||||
#define MXC_CCM_CISR_AXI_A_PODF_LOADED (0x1 << 17)
|
||||
#define MXC_CCM_CISR_DIVIDER_LOADED (0x1 << 16)
|
||||
#define MXC_CCM_CISR_COSC_READY (0x1 << 6)
|
||||
#define MXC_CCM_CISR_CKIH2_READY (0x1 << 5)
|
||||
#define MXC_CCM_CISR_CKIH_READY (0x1 << 4)
|
||||
#define MXC_CCM_CISR_FPM_READY (0x1 << 3)
|
||||
#define MXC_CCM_CISR_LRF_PLL3 (0x1 << 2)
|
||||
#define MXC_CCM_CISR_LRF_PLL2 (0x1 << 1)
|
||||
#define MXC_CCM_CISR_LRF_PLL1 (0x1)
|
||||
|
||||
/* Define the bits in register CIMR */
|
||||
#define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED (0x1 << 25)
|
||||
#define MXC_CCM_CIMR_MASK_NFC_IPG_INT_MEM_PODF_LOADED (0x1 << 21)
|
||||
#define MXC_CCM_CIMR_MASK_EMI_PODF_LOADED (0x1 << 20)
|
||||
#define MXC_CCM_CIMR_MASK_AXI_C_PODF_LOADED (0x1 << 19)
|
||||
#define MXC_CCM_CIMR_MASK_AXI_B_PODF_LOADED (0x1 << 18)
|
||||
#define MXC_CCM_CIMR_MASK_AXI_A_PODF_LOADED (0x1 << 17)
|
||||
#define MXC_CCM_CIMR_MASK_DIVIDER_LOADED (0x1 << 16)
|
||||
#define MXC_CCM_CIMR_MASK_COSC_READY (0x1 << 5)
|
||||
#define MXC_CCM_CIMR_MASK_CKIH_READY (0x1 << 4)
|
||||
#define MXC_CCM_CIMR_MASK_FPM_READY (0x1 << 3)
|
||||
#define MXC_CCM_CIMR_MASK_LRF_PLL3 (0x1 << 2)
|
||||
#define MXC_CCM_CIMR_MASK_LRF_PLL2 (0x1 << 1)
|
||||
#define MXC_CCM_CIMR_MASK_LRF_PLL1 (0x1)
|
||||
|
||||
/* Define the bits in register CCOSR */
|
||||
#define MXC_CCM_CCOSR_CKO2_EN_OFFSET (0x1 << 24)
|
||||
#define MXC_CCM_CCOSR_CKO2_DIV_OFFSET (21)
|
||||
#define MXC_CCM_CCOSR_CKO2_DIV_MASK (0x7 << 21)
|
||||
#define MXC_CCM_CCOSR_CKO2_SEL_OFFSET (16)
|
||||
#define MXC_CCM_CCOSR_CKO2_SEL_MASK (0x1F << 16)
|
||||
#define MXC_CCM_CCOSR_CKOL_EN (0x1 << 7)
|
||||
#define MXC_CCM_CCOSR_CKOL_DIV_OFFSET (4)
|
||||
#define MXC_CCM_CCOSR_CKOL_DIV_MASK (0x7 << 4)
|
||||
#define MXC_CCM_CCOSR_CKOL_SEL_OFFSET (0)
|
||||
#define MXC_CCM_CCOSR_CKOL_SEL_MASK (0xF)
|
||||
|
||||
/* Define the bits in registers CGPR */
|
||||
#define MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE (0x1 << 4)
|
||||
#define MXC_CCM_CGPR_FPM_SEL (0x1 << 3)
|
||||
#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_OFFSET (0)
|
||||
#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_MASK (0x7)
|
||||
|
||||
/* Define the bits in registers CCGRx */
|
||||
#define MXC_CCM_CCGR_CG_MASK 0x3
|
||||
|
||||
#define MXC_CCM_CCGR0_CG15_OFFSET 30
|
||||
#define MXC_CCM_CCGR0_CG15_MASK (0x3 << 30)
|
||||
#define MXC_CCM_CCGR0_CG14_OFFSET 28
|
||||
#define MXC_CCM_CCGR0_CG14_MASK (0x3 << 28)
|
||||
#define MXC_CCM_CCGR0_CG13_OFFSET 26
|
||||
#define MXC_CCM_CCGR0_CG13_MASK (0x3 << 26)
|
||||
#define MXC_CCM_CCGR0_CG12_OFFSET 24
|
||||
#define MXC_CCM_CCGR0_CG12_MASK (0x3 << 24)
|
||||
#define MXC_CCM_CCGR0_CG11_OFFSET 22
|
||||
#define MXC_CCM_CCGR0_CG11_MASK (0x3 << 22)
|
||||
#define MXC_CCM_CCGR0_CG10_OFFSET 20
|
||||
#define MXC_CCM_CCGR0_CG10_MASK (0x3 << 20)
|
||||
#define MXC_CCM_CCGR0_CG9_OFFSET 18
|
||||
#define MXC_CCM_CCGR0_CG9_MASK (0x3 << 18)
|
||||
#define MXC_CCM_CCGR0_CG8_OFFSET 16
|
||||
#define MXC_CCM_CCGR0_CG8_MASK (0x3 << 16)
|
||||
#define MXC_CCM_CCGR0_CG7_OFFSET 14
|
||||
#define MXC_CCM_CCGR0_CG6_OFFSET 12
|
||||
#define MXC_CCM_CCGR0_CG5_OFFSET 10
|
||||
#define MXC_CCM_CCGR0_CG5_MASK (0x3 << 10)
|
||||
#define MXC_CCM_CCGR0_CG4_OFFSET 8
|
||||
#define MXC_CCM_CCGR0_CG4_MASK (0x3 << 8)
|
||||
#define MXC_CCM_CCGR0_CG3_OFFSET 6
|
||||
#define MXC_CCM_CCGR0_CG3_MASK (0x3 << 6)
|
||||
#define MXC_CCM_CCGR0_CG2_OFFSET 4
|
||||
#define MXC_CCM_CCGR0_CG2_MASK (0x3 << 4)
|
||||
#define MXC_CCM_CCGR0_CG1_OFFSET 2
|
||||
#define MXC_CCM_CCGR0_CG1_MASK (0x3 << 2)
|
||||
#define MXC_CCM_CCGR0_CG0_OFFSET 0
|
||||
#define MXC_CCM_CCGR0_CG0_MASK 0x3
|
||||
|
||||
#define MXC_CCM_CCGR1_CG15_OFFSET 30
|
||||
#define MXC_CCM_CCGR1_CG14_OFFSET 28
|
||||
#define MXC_CCM_CCGR1_CG13_OFFSET 26
|
||||
#define MXC_CCM_CCGR1_CG12_OFFSET 24
|
||||
#define MXC_CCM_CCGR1_CG11_OFFSET 22
|
||||
#define MXC_CCM_CCGR1_CG10_OFFSET 20
|
||||
#define MXC_CCM_CCGR1_CG9_OFFSET 18
|
||||
#define MXC_CCM_CCGR1_CG8_OFFSET 16
|
||||
#define MXC_CCM_CCGR1_CG7_OFFSET 14
|
||||
#define MXC_CCM_CCGR1_CG6_OFFSET 12
|
||||
#define MXC_CCM_CCGR1_CG5_OFFSET 10
|
||||
#define MXC_CCM_CCGR1_CG4_OFFSET 8
|
||||
#define MXC_CCM_CCGR1_CG3_OFFSET 6
|
||||
#define MXC_CCM_CCGR1_CG2_OFFSET 4
|
||||
#define MXC_CCM_CCGR1_CG1_OFFSET 2
|
||||
#define MXC_CCM_CCGR1_CG0_OFFSET 0
|
||||
|
||||
#define MXC_CCM_CCGR2_CG15_OFFSET 30
|
||||
#define MXC_CCM_CCGR2_CG14_OFFSET 28
|
||||
#define MXC_CCM_CCGR2_CG13_OFFSET 26
|
||||
#define MXC_CCM_CCGR2_CG12_OFFSET 24
|
||||
#define MXC_CCM_CCGR2_CG11_OFFSET 22
|
||||
#define MXC_CCM_CCGR2_CG10_OFFSET 20
|
||||
#define MXC_CCM_CCGR2_CG9_OFFSET 18
|
||||
#define MXC_CCM_CCGR2_CG8_OFFSET 16
|
||||
#define MXC_CCM_CCGR2_CG7_OFFSET 14
|
||||
#define MXC_CCM_CCGR2_CG6_OFFSET 12
|
||||
#define MXC_CCM_CCGR2_CG5_OFFSET 10
|
||||
#define MXC_CCM_CCGR2_CG4_OFFSET 8
|
||||
#define MXC_CCM_CCGR2_CG3_OFFSET 6
|
||||
#define MXC_CCM_CCGR2_CG2_OFFSET 4
|
||||
#define MXC_CCM_CCGR2_CG1_OFFSET 2
|
||||
#define MXC_CCM_CCGR2_CG0_OFFSET 0
|
||||
|
||||
#define MXC_CCM_CCGR3_CG15_OFFSET 30
|
||||
#define MXC_CCM_CCGR3_CG14_OFFSET 28
|
||||
#define MXC_CCM_CCGR3_CG13_OFFSET 26
|
||||
#define MXC_CCM_CCGR3_CG12_OFFSET 24
|
||||
#define MXC_CCM_CCGR3_CG11_OFFSET 22
|
||||
#define MXC_CCM_CCGR3_CG10_OFFSET 20
|
||||
#define MXC_CCM_CCGR3_CG9_OFFSET 18
|
||||
#define MXC_CCM_CCGR3_CG8_OFFSET 16
|
||||
#define MXC_CCM_CCGR3_CG7_OFFSET 14
|
||||
#define MXC_CCM_CCGR3_CG6_OFFSET 12
|
||||
#define MXC_CCM_CCGR3_CG5_OFFSET 10
|
||||
#define MXC_CCM_CCGR3_CG4_OFFSET 8
|
||||
#define MXC_CCM_CCGR3_CG3_OFFSET 6
|
||||
#define MXC_CCM_CCGR3_CG2_OFFSET 4
|
||||
#define MXC_CCM_CCGR3_CG1_OFFSET 2
|
||||
#define MXC_CCM_CCGR3_CG0_OFFSET 0
|
||||
|
||||
#define MXC_CCM_CCGR4_CG15_OFFSET 30
|
||||
#define MXC_CCM_CCGR4_CG14_OFFSET 28
|
||||
#define MXC_CCM_CCGR4_CG13_OFFSET 26
|
||||
#define MXC_CCM_CCGR4_CG12_OFFSET 24
|
||||
#define MXC_CCM_CCGR4_CG11_OFFSET 22
|
||||
#define MXC_CCM_CCGR4_CG10_OFFSET 20
|
||||
#define MXC_CCM_CCGR4_CG9_OFFSET 18
|
||||
#define MXC_CCM_CCGR4_CG8_OFFSET 16
|
||||
#define MXC_CCM_CCGR4_CG7_OFFSET 14
|
||||
#define MXC_CCM_CCGR4_CG6_OFFSET 12
|
||||
#define MXC_CCM_CCGR4_CG5_OFFSET 10
|
||||
#define MXC_CCM_CCGR4_CG4_OFFSET 8
|
||||
#define MXC_CCM_CCGR4_CG3_OFFSET 6
|
||||
#define MXC_CCM_CCGR4_CG2_OFFSET 4
|
||||
#define MXC_CCM_CCGR4_CG1_OFFSET 2
|
||||
#define MXC_CCM_CCGR4_CG0_OFFSET 0
|
||||
|
||||
#define MXC_CCM_CCGR5_CG15_OFFSET 30
|
||||
#define MXC_CCM_CCGR5_CG14_OFFSET 28
|
||||
#define MXC_CCM_CCGR5_CG14_MASK (0x3 << 28)
|
||||
#define MXC_CCM_CCGR5_CG13_OFFSET 26
|
||||
#define MXC_CCM_CCGR5_CG13_MASK (0x3 << 26)
|
||||
#define MXC_CCM_CCGR5_CG12_OFFSET 24
|
||||
#define MXC_CCM_CCGR5_CG12_MASK (0x3 << 24)
|
||||
#define MXC_CCM_CCGR5_CG11_OFFSET 22
|
||||
#define MXC_CCM_CCGR5_CG11_MASK (0x3 << 22)
|
||||
#define MXC_CCM_CCGR5_CG10_OFFSET 20
|
||||
#define MXC_CCM_CCGR5_CG10_MASK (0x3 << 20)
|
||||
#define MXC_CCM_CCGR5_CG9_OFFSET 18
|
||||
#define MXC_CCM_CCGR5_CG9_MASK (0x3 << 18)
|
||||
#define MXC_CCM_CCGR5_CG8_OFFSET 16
|
||||
#define MXC_CCM_CCGR5_CG8_MASK (0x3 << 16)
|
||||
#define MXC_CCM_CCGR5_CG7_OFFSET 14
|
||||
#define MXC_CCM_CCGR5_CG7_MASK (0x3 << 14)
|
||||
#define MXC_CCM_CCGR5_CG6_OFFSET 12
|
||||
#define MXC_CCM_CCGR5_CG5_OFFSET 10
|
||||
#define MXC_CCM_CCGR5_CG4_OFFSET 8
|
||||
#define MXC_CCM_CCGR5_CG3_OFFSET 6
|
||||
#define MXC_CCM_CCGR5_CG2_OFFSET 4
|
||||
#define MXC_CCM_CCGR5_CG2_MASK (0x3 << 4)
|
||||
#define MXC_CCM_CCGR5_CG1_OFFSET 2
|
||||
#define MXC_CCM_CCGR5_CG0_OFFSET 0
|
||||
|
||||
#define MXC_CCM_CCGR6_CG4_OFFSET 8
|
||||
#define MXC_CCM_CCGR6_CG4_MASK (0x3 << 8)
|
||||
#define MXC_CCM_CCGR6_CG3_OFFSET 6
|
||||
#define MXC_CCM_CCGR6_CG2_OFFSET 4
|
||||
#define MXC_CCM_CCGR6_CG1_OFFSET 2
|
||||
#define MXC_CCM_CCGR6_CG0_OFFSET 0
|
||||
|
||||
#define MXC_CORTEXA8_BASE ARM_BASE_ADDR
|
||||
#define MXC_GPC_BASE GPC_BASE_ADDR
|
||||
#define MXC_DPTC_LP_BASE (GPC_BASE_ADDR + 0x80)
|
||||
#define MXC_DPTC_GP_BASE (GPC_BASE_ADDR + 0x100)
|
||||
#define MXC_DVFS_CORE_BASE (GPC_BASE_ADDR + 0x180)
|
||||
#define MXC_DPTC_PER_BASE (GPC_BASE_ADDR + 0x1C0)
|
||||
#define MXC_PGC_IPU_BASE (GPC_BASE_ADDR + 0x220)
|
||||
#define MXC_PGC_VPU_BASE (GPC_BASE_ADDR + 0x240)
|
||||
#define MXC_PGC_GPU_BASE (GPC_BASE_ADDR + 0x260)
|
||||
#define MXC_SRPG_NEON_BASE (GPC_BASE_ADDR + 0x280)
|
||||
#define MXC_SRPG_ARM_BASE (GPC_BASE_ADDR + 0x2A0)
|
||||
#define MXC_SRPG_EMPGC0_BASE (GPC_BASE_ADDR + 0x2C0)
|
||||
#define MXC_SRPG_EMPGC1_BASE (GPC_BASE_ADDR + 0x2D0)
|
||||
#define MXC_SRPG_MEGAMIX_BASE (GPC_BASE_ADDR + 0x2E0)
|
||||
#define MXC_SRPG_EMI_BASE (GPC_BASE_ADDR + 0x300)
|
||||
|
||||
/* CORTEXA8 platform */
|
||||
#define MXC_CORTEXA8_PLAT_PVID (MXC_CORTEXA8_BASE + 0x0)
|
||||
#define MXC_CORTEXA8_PLAT_GPC (MXC_CORTEXA8_BASE + 0x4)
|
||||
#define MXC_CORTEXA8_PLAT_PIC (MXC_CORTEXA8_BASE + 0x8)
|
||||
#define MXC_CORTEXA8_PLAT_LPC (MXC_CORTEXA8_BASE + 0xC)
|
||||
#define MXC_CORTEXA8_PLAT_NEON_LPC (MXC_CORTEXA8_BASE + 0x10)
|
||||
#define MXC_CORTEXA8_PLAT_ICGC (MXC_CORTEXA8_BASE + 0x14)
|
||||
#define MXC_CORTEXA8_PLAT_AMC (MXC_CORTEXA8_BASE + 0x18)
|
||||
#define MXC_CORTEXA8_PLAT_NMC (MXC_CORTEXA8_BASE + 0x20)
|
||||
#define MXC_CORTEXA8_PLAT_NMS (MXC_CORTEXA8_BASE + 0x24)
|
||||
|
||||
/* DVFS CORE */
|
||||
#define MXC_DVFSTHRS (MXC_DVFS_CORE_BASE + 0x00)
|
||||
#define MXC_DVFSCOUN (MXC_DVFS_CORE_BASE + 0x04)
|
||||
#define MXC_DVFSSIG1 (MXC_DVFS_CORE_BASE + 0x08)
|
||||
#define MXC_DVFSSIG0 (MXC_DVFS_CORE_BASE + 0x0C)
|
||||
#define MXC_DVFSGPC0 (MXC_DVFS_CORE_BASE + 0x10)
|
||||
#define MXC_DVFSGPC1 (MXC_DVFS_CORE_BASE + 0x14)
|
||||
#define MXC_DVFSGPBT (MXC_DVFS_CORE_BASE + 0x18)
|
||||
#define MXC_DVFSEMAC (MXC_DVFS_CORE_BASE + 0x1C)
|
||||
#define MXC_DVFSCNTR (MXC_DVFS_CORE_BASE + 0x20)
|
||||
#define MXC_DVFSLTR0_0 (MXC_DVFS_CORE_BASE + 0x24)
|
||||
#define MXC_DVFSLTR0_1 (MXC_DVFS_CORE_BASE + 0x28)
|
||||
#define MXC_DVFSLTR1_0 (MXC_DVFS_CORE_BASE + 0x2C)
|
||||
#define MXC_DVFSLTR1_1 (MXC_DVFS_CORE_BASE + 0x30)
|
||||
#define MXC_DVFSPT0 (MXC_DVFS_CORE_BASE + 0x34)
|
||||
#define MXC_DVFSPT1 (MXC_DVFS_CORE_BASE + 0x38)
|
||||
#define MXC_DVFSPT2 (MXC_DVFS_CORE_BASE + 0x3C)
|
||||
#define MXC_DVFSPT3 (MXC_DVFS_CORE_BASE + 0x40)
|
||||
|
||||
/* GPC */
|
||||
#define MXC_GPC_CNTR (MXC_GPC_BASE + 0x0)
|
||||
#define MXC_GPC_PGR (MXC_GPC_BASE + 0x4)
|
||||
#define MXC_GPC_VCR (MXC_GPC_BASE + 0x8)
|
||||
#define MXC_GPC_ALL_PU (MXC_GPC_BASE + 0xC)
|
||||
#define MXC_GPC_NEON (MXC_GPC_BASE + 0x10)
|
||||
#define MXC_GPC_PGR_ARMPG_OFFSET 8
|
||||
#define MXC_GPC_PGR_ARMPG_MASK (3 << 8)
|
||||
|
||||
/* PGC */
|
||||
#define MXC_PGC_IPU_PGCR (MXC_PGC_IPU_BASE + 0x0)
|
||||
#define MXC_PGC_IPU_PGSR (MXC_PGC_IPU_BASE + 0xC)
|
||||
#define MXC_PGC_VPU_PGCR (MXC_PGC_VPU_BASE + 0x0)
|
||||
#define MXC_PGC_VPU_PGSR (MXC_PGC_VPU_BASE + 0xC)
|
||||
#define MXC_PGC_GPU_PGCR (MXC_PGC_GPU_BASE + 0x0)
|
||||
#define MXC_PGC_GPU_PGSR (MXC_PGC_GPU_BASE + 0xC)
|
||||
|
||||
#define MXC_PGCR_PCR 1
|
||||
#define MXC_SRPGCR_PCR 1
|
||||
#define MXC_EMPGCR_PCR 1
|
||||
#define MXC_PGSR_PSR 1
|
||||
|
||||
|
||||
#define MXC_CORTEXA8_PLAT_LPC_DSM (1 << 0)
|
||||
#define MXC_CORTEXA8_PLAT_LPC_DBG_DSM (1 << 1)
|
||||
|
||||
/* SRPG */
|
||||
#define MXC_SRPG_NEON_SRPGCR (MXC_SRPG_NEON_BASE + 0x0)
|
||||
#define MXC_SRPG_NEON_PUPSCR (MXC_SRPG_NEON_BASE + 0x4)
|
||||
#define MXC_SRPG_NEON_PDNSCR (MXC_SRPG_NEON_BASE + 0x8)
|
||||
|
||||
#define MXC_SRPG_ARM_SRPGCR (MXC_SRPG_ARM_BASE + 0x0)
|
||||
#define MXC_SRPG_ARM_PUPSCR (MXC_SRPG_ARM_BASE + 0x4)
|
||||
#define MXC_SRPG_ARM_PDNSCR (MXC_SRPG_ARM_BASE + 0x8)
|
||||
|
||||
#define MXC_SRPG_EMPGC0_SRPGCR (MXC_SRPG_EMPGC0_BASE + 0x0)
|
||||
#define MXC_SRPG_EMPGC0_PUPSCR (MXC_SRPG_EMPGC0_BASE + 0x4)
|
||||
#define MXC_SRPG_EMPGC0_PDNSCR (MXC_SRPG_EMPGC0_BASE + 0x8)
|
||||
|
||||
#define MXC_SRPG_EMPGC1_SRPGCR (MXC_SRPG_EMPGC1_BASE + 0x0)
|
||||
#define MXC_SRPG_EMPGC1_PUPSCR (MXC_SRPG_EMPGC1_BASE + 0x4)
|
||||
#define MXC_SRPG_EMPGC1_PDNSCR (MXC_SRPG_EMPGC1_BASE + 0x8)
|
||||
|
||||
#define MXC_SRPG_MEGAMIX_SRPGCR (MXC_SRPG_MEGAMIX_BASE + 0x0)
|
||||
#define MXC_SRPG_MEGAMIX_PUPSCR (MXC_SRPG_MEGAMIX_BASE + 0x4)
|
||||
#define MXC_SRPG_MEGAMIX_PDNSCR (MXC_SRPG_MEGAMIX_BASE + 0x8)
|
||||
|
||||
#define MXC_SRPGC_EMI_SRPGCR (MXC_SRPGC_EMI_BASE + 0x0)
|
||||
#define MXC_SRPGC_EMI_PUPSCR (MXC_SRPGC_EMI_BASE + 0x4)
|
||||
#define MXC_SRPGC_EMI_PDNSCR (MXC_SRPGC_EMI_BASE + 0x8)
|
||||
|
||||
#endif /* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */
|
||||
260
cpu/arm_cortexa8/mx51/generic.c
Normal file
260
cpu/arm_cortexa8/mx51/generic.c
Normal file
@ -0,0 +1,260 @@
|
||||
/*
|
||||
* (C) Copyright 2007
|
||||
* Sascha Hauer, Pengutronix
|
||||
*
|
||||
* (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <common.h>
|
||||
#include <asm/arch/mx51.h>
|
||||
#include <asm/errno.h>
|
||||
#include "crm_regs.h"
|
||||
|
||||
enum pll_clocks {
|
||||
PLL1_CLK = MXC_DPLL1_BASE,
|
||||
PLL2_CLK = MXC_DPLL2_BASE,
|
||||
PLL3_CLK = MXC_DPLL3_BASE,
|
||||
};
|
||||
|
||||
enum pll_sw_clocks {
|
||||
PLL1_SW_CLK,
|
||||
PLL2_SW_CLK,
|
||||
PLL3_SW_CLK,
|
||||
};
|
||||
|
||||
static u32 __decode_pll(enum pll_clocks pll, u32 infreq)
|
||||
{
|
||||
u32 mfi, mfn, mfd, pd;
|
||||
|
||||
mfn = __REG(pll + MXC_PLL_DP_MFN);
|
||||
mfd = __REG(pll + MXC_PLL_DP_MFD) + 1;
|
||||
mfi = __REG(pll + MXC_PLL_DP_OP);
|
||||
pd = (mfi & 0xF) + 1;
|
||||
mfi = (mfi >> 4) & 0xF;
|
||||
mfi = (mfi >= 5) ? mfi : 5;
|
||||
|
||||
return ((4 * (infreq / 1000) * (mfi * mfd + mfn)) / (mfd * pd)) * 1000;
|
||||
}
|
||||
|
||||
static u32 __get_mcu_main_clk(void)
|
||||
{
|
||||
u32 reg, freq;
|
||||
reg = (__REG(MXC_CCM_CACRR) & MXC_CCM_CACRR_ARM_PODF_MASK) >>
|
||||
MXC_CCM_CACRR_ARM_PODF_OFFSET;
|
||||
freq = __decode_pll(PLL1_CLK, CONFIG_MX51_HCLK_FREQ);
|
||||
return freq / (reg + 1);
|
||||
}
|
||||
|
||||
static u32 __get_periph_clk(void)
|
||||
{
|
||||
u32 reg;
|
||||
reg = __REG(MXC_CCM_CBCDR);
|
||||
if (reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL) {
|
||||
reg = __REG(MXC_CCM_CBCMR);
|
||||
switch ((reg & MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK) >>
|
||||
MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET) {
|
||||
case 0:
|
||||
return __decode_pll(PLL1_CLK, CONFIG_MX51_HCLK_FREQ);
|
||||
case 1:
|
||||
return __decode_pll(PLL3_CLK, CONFIG_MX51_HCLK_FREQ);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return __decode_pll(PLL2_CLK, CONFIG_MX51_HCLK_FREQ);
|
||||
}
|
||||
|
||||
static u32 __get_ipg_clk(void)
|
||||
{
|
||||
u32 ahb_podf, ipg_podf;
|
||||
|
||||
ahb_podf = __REG(MXC_CCM_CBCDR);
|
||||
ipg_podf = (ahb_podf & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
|
||||
MXC_CCM_CBCDR_IPG_PODF_OFFSET;
|
||||
ahb_podf = (ahb_podf & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
|
||||
MXC_CCM_CBCDR_AHB_PODF_OFFSET;
|
||||
return __get_periph_clk() / ((ahb_podf + 1) * (ipg_podf + 1));
|
||||
}
|
||||
|
||||
static u32 __get_ipg_per_clk(void)
|
||||
{
|
||||
u32 pred1, pred2, podf;
|
||||
if (__REG(MXC_CCM_CBCMR) & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL)
|
||||
return __get_ipg_clk();
|
||||
/* Fixme: not handle what about lpm*/
|
||||
podf = __REG(MXC_CCM_CBCDR);
|
||||
pred1 = (podf & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
|
||||
MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET;
|
||||
pred2 = (podf & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
|
||||
MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET;
|
||||
podf = (podf & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
|
||||
MXC_CCM_CBCDR_PERCLK_PODF_OFFSET;
|
||||
|
||||
return __get_periph_clk() / ((pred1 + 1) * (pred2 + 1) * (podf + 1));
|
||||
}
|
||||
|
||||
static u32 __get_uart_clk(void)
|
||||
{
|
||||
unsigned int freq, reg, pred, podf;
|
||||
reg = __REG(MXC_CCM_CSCMR1);
|
||||
switch ((reg & MXC_CCM_CSCMR1_UART_CLK_SEL_MASK) >>
|
||||
MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET) {
|
||||
case 0x0:
|
||||
freq = __decode_pll(PLL1_CLK, CONFIG_MX51_HCLK_FREQ);
|
||||
break;
|
||||
case 0x1:
|
||||
freq = __decode_pll(PLL2_CLK, CONFIG_MX51_HCLK_FREQ);
|
||||
break;
|
||||
case 0x2:
|
||||
freq = __decode_pll(PLL3_CLK, CONFIG_MX51_HCLK_FREQ);
|
||||
break;
|
||||
default:
|
||||
return 66500000;
|
||||
}
|
||||
|
||||
reg = __REG(MXC_CCM_CSCDR1);
|
||||
|
||||
pred = (reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >>
|
||||
MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET;
|
||||
|
||||
podf = (reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
|
||||
MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET;
|
||||
freq /= (pred + 1) * (podf + 1);
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
/*!
|
||||
+ * This function returns the low power audio clock.
|
||||
+ */
|
||||
u32 get_lp_apm(void)
|
||||
{
|
||||
u32 ret_val = 0;
|
||||
u32 ccsr = __REG(MXC_CCM_CCSR);
|
||||
|
||||
if (((ccsr >> 9) & 1) == 0)
|
||||
ret_val = CONFIG_MX51_HCLK_FREQ;
|
||||
else
|
||||
ret_val = ((32768 * 1024));
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static u32 __get_cspi_clk(void)
|
||||
{
|
||||
u32 ret_val = 0, pdf, pre_pdf, clk_sel;
|
||||
u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
|
||||
u32 cscdr2 = __REG(MXC_CCM_CSCDR2);
|
||||
|
||||
pre_pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) \
|
||||
>> MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET;
|
||||
pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) \
|
||||
>> MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET;
|
||||
clk_sel = (cscmr1 & MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK) \
|
||||
>> MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET;
|
||||
|
||||
switch (clk_sel) {
|
||||
case 0:
|
||||
ret_val = __decode_pll(PLL1_CLK, CONFIG_MX51_HCLK_FREQ) / ((pre_pdf + 1) * (pdf + 1));
|
||||
break;
|
||||
case 1:
|
||||
ret_val = __decode_pll(PLL2_CLK, CONFIG_MX51_HCLK_FREQ) / ((pre_pdf + 1) * (pdf + 1));
|
||||
break;
|
||||
case 2:
|
||||
ret_val = __decode_pll(PLL3_CLK, CONFIG_MX51_HCLK_FREQ) / ((pre_pdf + 1) * (pdf + 1));
|
||||
break;
|
||||
default:
|
||||
ret_val = get_lp_apm() / ((pre_pdf + 1) * (pdf + 1));
|
||||
break;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
unsigned int mxc_get_clock(enum mxc_clock clk)
|
||||
{
|
||||
switch (clk) {
|
||||
case MXC_ARM_CLK:
|
||||
return __get_mcu_main_clk();
|
||||
case MXC_AHB_CLK:
|
||||
break;
|
||||
case MXC_IPG_CLK:
|
||||
return __get_ipg_clk();
|
||||
case MXC_IPG_PERCLK:
|
||||
return __get_ipg_per_clk();
|
||||
case MXC_UART_CLK:
|
||||
return __get_uart_clk();
|
||||
case MXC_CSPI_CLK:
|
||||
return __get_cspi_clk();
|
||||
case MXC_FEC_CLK:
|
||||
return __decode_pll(PLL1_CLK, CONFIG_MX51_HCLK_FREQ);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void mxc_dump_clocks(void)
|
||||
{
|
||||
u32 freq;
|
||||
freq = __decode_pll(PLL1_CLK, CONFIG_MX51_HCLK_FREQ);
|
||||
printf("mx51 pll1: %dMHz\n", freq / 1000000);
|
||||
freq = __decode_pll(PLL2_CLK, CONFIG_MX51_HCLK_FREQ);
|
||||
printf("mx51 pll2: %dMHz\n", freq / 1000000);
|
||||
freq = __decode_pll(PLL3_CLK, CONFIG_MX51_HCLK_FREQ);
|
||||
printf("mx51 pll3: %dMHz\n", freq / 1000000);
|
||||
printf("ipg clock : %dHz\n", mxc_get_clock(MXC_IPG_CLK));
|
||||
printf("ipg per clock : %dHz\n", mxc_get_clock(MXC_IPG_PERCLK));
|
||||
printf("uart clock : %dHz\n", mxc_get_clock(MXC_UART_CLK));
|
||||
printf("cspi clock : %dHz\n", mxc_get_clock(MXC_CSPI_CLK));
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DISPLAY_CPUINFO)
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
printf("CPU: Freescale i.MX51 family %d.%dV at %d MHz\n",
|
||||
(get_board_rev() & 0xFF) >> 4,
|
||||
(get_board_rev() & 0xF),
|
||||
__get_mcu_main_clk() / 1000000);
|
||||
mxc_dump_clocks();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initializes on-chip ethernet controllers.
|
||||
* to override, implement board_eth_init()
|
||||
*/
|
||||
#if defined(CONFIG_MXC_FEC)
|
||||
extern int mxc_fec_initialize(bd_t *bis);
|
||||
#endif
|
||||
|
||||
int cpu_eth_init(bd_t *bis)
|
||||
{
|
||||
int rc = -ENODEV;
|
||||
|
||||
#if defined(CONFIG_MXC_FEC)
|
||||
rc = mxc_fec_initialize(bis);
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
128
cpu/arm_cortexa8/mx51/interrupts.c
Normal file
128
cpu/arm_cortexa8/mx51/interrupts.c
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* (C) Copyright 2007
|
||||
* Sascha Hauer, Pengutronix
|
||||
*
|
||||
* (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <common.h>
|
||||
#include <asm/arch/mx51.h>
|
||||
|
||||
/* General purpose timers registers */
|
||||
#define GPTCR __REG(GPT1_BASE_ADDR) /* Control register */
|
||||
#define GPTPR __REG(GPT1_BASE_ADDR + 0x4) /* Prescaler register */
|
||||
#define GPTSR __REG(GPT1_BASE_ADDR + 0x8) /* Status register */
|
||||
#define GPTCNT __REG(GPT1_BASE_ADDR + 0x24) /* Counter register */
|
||||
|
||||
/* General purpose timers bitfields */
|
||||
#define GPTCR_SWR (1<<15) /* Software reset */
|
||||
#define GPTCR_FRR (1<<9) /* Freerun / restart */
|
||||
#define GPTCR_CLKSOURCE_32 (4<<6) /* Clock source */
|
||||
#define GPTCR_TEN (1) /* Timer enable */
|
||||
|
||||
static inline void setup_gpt()
|
||||
{
|
||||
int i;
|
||||
static int init_done;
|
||||
|
||||
if (init_done)
|
||||
return;
|
||||
|
||||
init_done = 1;
|
||||
|
||||
/* setup GP Timer 1 */
|
||||
GPTCR = GPTCR_SWR;
|
||||
for (i = 0; i < 100; i++)
|
||||
GPTCR = 0; /* We have no udelay by now */
|
||||
GPTPR = 0; /* 32Khz */
|
||||
/* Freerun Mode, PERCLK1 input */
|
||||
GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN;
|
||||
}
|
||||
|
||||
/* nothing really to do with interrupts, just starts up a counter. */
|
||||
int interrupt_init(void)
|
||||
{
|
||||
setup_gpt();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void reset_timer(void)
|
||||
{
|
||||
reset_timer_masked();
|
||||
}
|
||||
|
||||
void reset_timer_masked(void)
|
||||
{
|
||||
GPTCR = 0;
|
||||
/* Freerun Mode, PERCLK1 input */
|
||||
GPTCR = GPTCR_CLKSOURCE_32 | GPTCR_TEN;
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
ulong val = GPTCNT;
|
||||
return val;
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return get_timer_masked() - base;
|
||||
}
|
||||
|
||||
void set_timer(ulong t)
|
||||
{
|
||||
}
|
||||
|
||||
/* delay x useconds AND perserve advance timstamp value */
|
||||
void udelay(unsigned long usec)
|
||||
{
|
||||
ulong tmo, tmp;
|
||||
|
||||
setup_gpt();
|
||||
|
||||
/* if "big" number, spread normalization to seconds */
|
||||
if (usec >= 1000) {
|
||||
/* start to normalize for usec to ticks per sec */
|
||||
tmo = usec / 1000;
|
||||
/* find number of "ticks" to wait to achieve target */
|
||||
tmo *= CONFIG_SYS_HZ;
|
||||
tmo /= 1000; /* finish normalize. */
|
||||
} else {/* else small number, don't kill it prior to HZ multiply */
|
||||
tmo = usec * CONFIG_SYS_HZ;
|
||||
tmo /= (1000 * 1000);
|
||||
}
|
||||
|
||||
tmp = get_timer(0); /* get current timestamp */
|
||||
/* if setting this forward will roll time stamp */
|
||||
if ((tmo + tmp + 1) < tmp)
|
||||
/* reset "advancing" timestamp to 0, set lastinc value */
|
||||
reset_timer_masked();
|
||||
else /* else, set advancing stamp wake up time */
|
||||
tmo += tmp;
|
||||
while (get_timer_masked() < tmo) /* loop till event */
|
||||
/*NOP*/;
|
||||
}
|
||||
|
||||
void reset_cpu(ulong addr)
|
||||
{
|
||||
__REG16(WDOG1_BASE_ADDR) = 4;
|
||||
}
|
||||
199
cpu/arm_cortexa8/mx51/iomux.c
Normal file
199
cpu/arm_cortexa8/mx51/iomux.c
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @defgroup GPIO_MX51 Board GPIO and Muxing Setup
|
||||
* @ingroup MSL_MX51
|
||||
*/
|
||||
/*!
|
||||
* @file mach-mx51/iomux.c
|
||||
*
|
||||
* @brief I/O Muxing control functions
|
||||
*
|
||||
* @ingroup GPIO_MX51
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/mx51.h>
|
||||
#include <asm/arch/mx51_pins.h>
|
||||
#include <asm/arch/iomux.h>
|
||||
|
||||
/*!
|
||||
* IOMUX register (base) addresses
|
||||
*/
|
||||
enum iomux_reg_addr {
|
||||
IOMUXGPR0 = IOMUXC_BASE_ADDR,
|
||||
IOMUXGPR1 = IOMUXC_BASE_ADDR + 0x004,
|
||||
IOMUXSW_MUX_CTL = IOMUXC_BASE_ADDR,
|
||||
IOMUXSW_MUX_END = IOMUXC_BASE_ADDR + MUX_I_END,
|
||||
IOMUXSW_PAD_CTL = IOMUXC_BASE_ADDR + PAD_I_START,
|
||||
IOMUXSW_INPUT_CTL = IOMUXC_BASE_ADDR,
|
||||
};
|
||||
|
||||
#define MUX_PIN_NUM_MAX (((MUX_I_END - MUX_I_START) >> 2) + 1)
|
||||
|
||||
static inline u32 _get_mux_reg(iomux_pin_name_t pin)
|
||||
{
|
||||
u32 mux_reg = PIN_TO_IOMUX_MUX(pin);
|
||||
|
||||
if (is_soc_rev(CHIP_REV_2_0) < 0) {
|
||||
if ((pin == MX51_PIN_NANDF_RB5) ||
|
||||
(pin == MX51_PIN_NANDF_RB6) ||
|
||||
(pin == MX51_PIN_NANDF_RB7))
|
||||
; /* Do nothing */
|
||||
else if (mux_reg >= 0x2FC)
|
||||
mux_reg += 8;
|
||||
else if (mux_reg >= 0x130)
|
||||
mux_reg += 0xC;
|
||||
}
|
||||
mux_reg += IOMUXSW_MUX_CTL;
|
||||
return mux_reg;
|
||||
}
|
||||
|
||||
static inline u32 _get_pad_reg(iomux_pin_name_t pin)
|
||||
{
|
||||
u32 pad_reg = PIN_TO_IOMUX_PAD(pin);
|
||||
|
||||
if (is_soc_rev(CHIP_REV_2_0) < 0) {
|
||||
if ((pin == MX51_PIN_NANDF_RB5) ||
|
||||
(pin == MX51_PIN_NANDF_RB6) ||
|
||||
(pin == MX51_PIN_NANDF_RB7))
|
||||
; /* Do nothing */
|
||||
else if (pad_reg == 0x4D0 - PAD_I_START)
|
||||
pad_reg += 0x4C;
|
||||
else if (pad_reg == 0x860 - PAD_I_START)
|
||||
pad_reg += 0x9C;
|
||||
else if (pad_reg >= 0x804 - PAD_I_START)
|
||||
pad_reg += 0xB0;
|
||||
else if (pad_reg >= 0x7FC - PAD_I_START)
|
||||
pad_reg += 0xB4;
|
||||
else if (pad_reg >= 0x4E4 - PAD_I_START)
|
||||
pad_reg += 0xCC;
|
||||
else
|
||||
pad_reg += 8;
|
||||
}
|
||||
pad_reg += IOMUXSW_PAD_CTL;
|
||||
return pad_reg;
|
||||
}
|
||||
|
||||
static inline u32 _get_mux_end()
|
||||
{
|
||||
if (is_soc_rev(CHIP_REV_2_0) < 0)
|
||||
return IOMUXC_BASE_ADDR + (0x3F8 - 4);
|
||||
else
|
||||
return IOMUXC_BASE_ADDR + (0x3F0 - 4);
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function is used to configure a pin through the IOMUX module.
|
||||
* FIXED ME: for backward compatible. Will be static function!
|
||||
* @param pin a pin number as defined in \b #iomux_pin_name_t
|
||||
* @param cfg an output function as defined in \b #iomux_pin_cfg_t
|
||||
*
|
||||
* @return 0 if successful; Non-zero otherwise
|
||||
*/
|
||||
static int iomux_config_mux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
|
||||
{
|
||||
u32 mux_reg = _get_mux_reg(pin);
|
||||
|
||||
if ((mux_reg > _get_mux_end()) || (mux_reg < IOMUXSW_MUX_CTL))
|
||||
return -1;
|
||||
if (cfg == IOMUX_CONFIG_GPIO)
|
||||
writel(PIN_TO_ALT_GPIO(pin), mux_reg);
|
||||
else
|
||||
writel(cfg, mux_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Request ownership for an IO pin. This function has to be the first one
|
||||
* being called before that pin is used. The caller has to check the
|
||||
* return value to make sure it returns 0.
|
||||
*
|
||||
* @param pin a name defined by \b iomux_pin_name_t
|
||||
* @param cfg an input function as defined in \b #iomux_pin_cfg_t
|
||||
*
|
||||
* @return 0 if successful; Non-zero otherwise
|
||||
*/
|
||||
int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
|
||||
{
|
||||
int ret = iomux_config_mux(pin, cfg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Release ownership for an IO pin
|
||||
*
|
||||
* @param pin a name defined by \b iomux_pin_name_t
|
||||
* @param cfg an input function as defined in \b #iomux_pin_cfg_t
|
||||
*/
|
||||
void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function configures the pad value for a IOMUX pin.
|
||||
*
|
||||
* @param pin a pin number as defined in \b #iomux_pin_name_t
|
||||
* @param config the ORed value of elements defined in \b #iomux_pad_config_t
|
||||
*/
|
||||
void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config)
|
||||
{
|
||||
u32 pad_reg = _get_pad_reg(pin);
|
||||
writel(config, pad_reg);
|
||||
}
|
||||
|
||||
unsigned int mxc_iomux_get_pad(iomux_pin_name_t pin)
|
||||
{
|
||||
u32 pad_reg = _get_pad_reg(pin);
|
||||
return readl(pad_reg);
|
||||
}
|
||||
/*!
|
||||
* This function configures input path.
|
||||
*
|
||||
* @param input index of input select register as defined in \b
|
||||
* #iomux_input_select_t
|
||||
* @param config the binary value of elements defined in \b
|
||||
* #iomux_input_config_t
|
||||
*/
|
||||
void mxc_iomux_set_input(iomux_input_select_t input, u32 config)
|
||||
{
|
||||
u32 reg = IOMUXSW_INPUT_CTL + (input << 2);
|
||||
|
||||
if (is_soc_rev(CHIP_REV_2_0) < 0) {
|
||||
if (input == MUX_IN_IPU_IPP_DI_0_IND_DISPB_SD_D_SELECT_INPUT)
|
||||
input -= 4;
|
||||
else if (input ==
|
||||
MUX_IN_IPU_IPP_DI_1_IND_DISPB_SD_D_SELECT_INPUT)
|
||||
input -= 3;
|
||||
else if (input >= MUX_IN_KPP_IPP_IND_COL_6_SELECT_INPUT)
|
||||
input -= 2;
|
||||
else if (input >=
|
||||
MUX_IN_HSC_MIPI_MIX_PAR_SISG_TRIG_SELECT_INPUT)
|
||||
input -= 5;
|
||||
else if (input >=
|
||||
MUX_IN_HSC_MIPI_MIX_IPP_IND_SENS1_DATA_EN_SELECT_INPUT)
|
||||
input -= 3;
|
||||
else if (input >= MUX_IN_ECSPI2_IPP_IND_SS_B_3_SELECT_INPUT)
|
||||
input -= 2;
|
||||
else if (input >= MUX_IN_CCM_PLL1_BYPASS_CLK_SELECT_INPUT)
|
||||
input -= 1;
|
||||
|
||||
reg += INPUT_CTL_START_TO1;
|
||||
} else {
|
||||
reg += INPUT_CTL_START;
|
||||
}
|
||||
|
||||
writel(config, reg);
|
||||
}
|
||||
167
cpu/arm_cortexa8/mx51/mxc_nand_load.S
Normal file
167
cpu/arm_cortexa8/mx51/mxc_nand_load.S
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include <asm/arch/mx51.h>
|
||||
.macro do_wait_op_done
|
||||
1: ldr r7, [r3, #0x2C]
|
||||
ands r7, r7, #0x80000000
|
||||
beq 1b
|
||||
mov r7, #0x0
|
||||
str r7, [r3, #0x2C]
|
||||
.endm // do_wait_op_done
|
||||
|
||||
.section ".text.load", "x"
|
||||
.globl mxc_nand_load
|
||||
/*
|
||||
* R0: NFC BUF base address
|
||||
* R1: NFC BUF data end address
|
||||
* R2: RAM destination offset address
|
||||
* R3: NFC IP control register base
|
||||
* R4: NAND block address
|
||||
* R5: RAM destination end address
|
||||
* R6: NFC DATA register base
|
||||
* R7 - r14: 8 working buffer registers
|
||||
*/
|
||||
mxc_nand_load:
|
||||
ldr r0, =NFC_BASE_ADDR_AXI
|
||||
add r1, r0, #NFC_BUF_SIZE
|
||||
|
||||
/* For non-nand-boot, directly quit */
|
||||
cmp pc, r0
|
||||
movlo pc, lr
|
||||
cmp pc, r1
|
||||
movhi pc, lr
|
||||
|
||||
mov r4, #NFC_BUF_SIZE
|
||||
/* Get NAND page size */
|
||||
ldr r3, =NFC_BASE_ADDR
|
||||
ldr r2, [r3, #0x24]
|
||||
and r2, r2, #0x3
|
||||
cmp r2, #1
|
||||
moveq r2, #0x800
|
||||
movlt r2, #0x200
|
||||
adrls r5, NFC_PAGE_MODE
|
||||
strls r2, [r5]
|
||||
/* Get actually pre-loading size*/
|
||||
subls r1, r1, #0x800
|
||||
subls r4, r4, #0x800
|
||||
|
||||
/* r1 ~ r3, r12, lr(r14) must not change in relocated operation */
|
||||
ldr r2, U_BOOT_NAND_START
|
||||
1: ldmia r0!, {r5-r11, r13}
|
||||
stmia r2!, {r5-r11, r13}
|
||||
cmp r0, r1
|
||||
blo 1b
|
||||
|
||||
ldr r0, CONST_0X0FFF
|
||||
ldr r5, U_BOOT_NAND_START
|
||||
and lr, lr, r0
|
||||
add lr, lr, r5
|
||||
and r12, r12, r0
|
||||
add r12, r12, r5
|
||||
add r5, r5, #0x8
|
||||
and r0, pc, r0
|
||||
add pc, r5, r0
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
adr r0, SAVE_REGS /* Save r12 & R14(lr) */
|
||||
str r12, [r0]
|
||||
str lr, [r0, #4]
|
||||
Copy_Main:
|
||||
ldr r0, =NFC_BASE_ADDR_AXI
|
||||
|
||||
add r6, r0, #0x1E00
|
||||
ldr r5, =_end /* Try get right image size */
|
||||
add r5, r2, #0x00040000 /* Fixme to get actual image size */
|
||||
|
||||
mov r7, #0xFF000000
|
||||
add r7, r7, #0x00FF0000
|
||||
str r7, [r3, #0x4]
|
||||
str r7, [r3, #0x8]
|
||||
str r7, [r3, #0xC]
|
||||
str r7, [r3, #0x10]
|
||||
str r7, [r3, #0x14]
|
||||
str r7, [r3, #0x18]
|
||||
str r7, [r3, #0x1C]
|
||||
str r7, [r3, #0x20]
|
||||
mov r8, #0x7
|
||||
mov r7, #0x84
|
||||
1: add r9, r7, r8, lsr #3
|
||||
str r9, [r3, #0x0]
|
||||
subs r8, r8, #0x01
|
||||
bne 1b
|
||||
|
||||
mov r7, #0
|
||||
str r7, [r3, #0x2C]
|
||||
|
||||
ldr r7, NFC_PAGE_MODE
|
||||
Read_Page:
|
||||
/* start_nfc_addr_ops1(pg_no, pg_off) */
|
||||
cmp r7, #0x800
|
||||
movgt r7, r4, lsr #12 /* Get the page number for 4K page */
|
||||
moveq r7, r4, lsr #11 /* Get the page number for 2K page */
|
||||
mov r7, r7, lsl #16
|
||||
str r7, [r6, #0x04] /* Set the address */
|
||||
|
||||
/* writel((FLASH_Read_Mode1_LG << 8) | FLASH_Read_Mode1, NAND_CMD_REG)*/
|
||||
mov r7, #0x3000
|
||||
str r7, [r6,#0x0]
|
||||
|
||||
/* writel(0x00000000, NAND_CONFIGURATION1_REG) */
|
||||
mov r7, #0x0
|
||||
str r7, [r6, #0x34]
|
||||
|
||||
/* start auto-read
|
||||
* writel(NAND_LAUNCH_AUTO_READ, NAND_LAUNCH_REG);
|
||||
*/
|
||||
mov r7, #0x80
|
||||
str r7, [r6, #0x40]
|
||||
|
||||
do_wait_op_done
|
||||
|
||||
Copy_Good_Blk:
|
||||
1: ldmia r0!, {r7-r14}
|
||||
stmia r2!, {r7-r14}
|
||||
cmp r0, r1
|
||||
blo 1b
|
||||
cmp r2, r5
|
||||
bge Copy_Main_done
|
||||
ldr r7, NFC_PAGE_MODE
|
||||
add r4, r4, r7
|
||||
ldr r0, =NFC_BASE_ADDR_AXI
|
||||
b Read_Page
|
||||
|
||||
Copy_Main_done:
|
||||
adr r0, SAVE_REGS
|
||||
ldr r12, [r0]
|
||||
ldr lr, [r0, #4]
|
||||
mov pc, lr
|
||||
|
||||
U_BOOT_NAND_START: .word TEXT_BASE
|
||||
CONST_0X0FFF: .word 0x0FFF
|
||||
NFC_PAGE_MODE: .word 0x1000
|
||||
SAVE_REGS: .word 0x0
|
||||
.word 0x0
|
||||
226
cpu/arm_cortexa8/mx51/serial.c
Normal file
226
cpu/arm_cortexa8/mx51/serial.c
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>
|
||||
*
|
||||
* (C) Copyright 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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>
|
||||
|
||||
#if defined CONFIG_MX51_UART
|
||||
|
||||
#include <asm/arch/mx51.h>
|
||||
|
||||
#ifdef CONFIG_MX51_UART1
|
||||
#define UART_PHYS UART1_BASE_ADDR
|
||||
#elif defined(CONFIG_MX51_UART2)
|
||||
#define UART_PHYS UART2_BASE_ADDR
|
||||
#elif defined(CONFIG_MX51_UART3)
|
||||
#define UART_PHYS UART3_BASE_ADDR
|
||||
#else
|
||||
#error "define CFG_MX51_UARTx to use the mx51 UART driver"
|
||||
#endif
|
||||
|
||||
/* Register definitions */
|
||||
#define URXD 0x0 /* Receiver Register */
|
||||
#define UTXD 0x40 /* Transmitter Register */
|
||||
#define UCR1 0x80 /* Control Register 1 */
|
||||
#define UCR2 0x84 /* Control Register 2 */
|
||||
#define UCR3 0x88 /* Control Register 3 */
|
||||
#define UCR4 0x8c /* Control Register 4 */
|
||||
#define UFCR 0x90 /* FIFO Control Register */
|
||||
#define USR1 0x94 /* Status Register 1 */
|
||||
#define USR2 0x98 /* Status Register 2 */
|
||||
#define UESC 0x9c /* Escape Character Register */
|
||||
#define UTIM 0xa0 /* Escape Timer Register */
|
||||
#define UBIR 0xa4 /* BRM Incremental Register */
|
||||
#define UBMR 0xa8 /* BRM Modulator Register */
|
||||
#define UBRC 0xac /* Baud Rate Count Register */
|
||||
#define UTS 0xb4 /* UART Test Register (mx31) */
|
||||
|
||||
/* UART Control Register Bit Fields.*/
|
||||
#define URXD_CHARRDY (1<<15)
|
||||
#define URXD_ERR (1<<14)
|
||||
#define URXD_OVRRUN (1<<13)
|
||||
#define URXD_FRMERR (1<<12)
|
||||
#define URXD_BRK (1<<11)
|
||||
#define URXD_PRERR (1<<10)
|
||||
#define UCR1_ADEN (1<<15) /* Auto dectect interrupt */
|
||||
#define UCR1_ADBR (1<<14) /* Auto detect baud rate */
|
||||
#define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */
|
||||
#define UCR1_IDEN (1<<12) /* Idle condition interrupt */
|
||||
#define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */
|
||||
#define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */
|
||||
#define UCR1_IREN (1<<7) /* Infrared interface enable */
|
||||
#define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */
|
||||
#define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */
|
||||
#define UCR1_SNDBRK (1<<4) /* Send break */
|
||||
#define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */
|
||||
#define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */
|
||||
#define UCR1_DOZE (1<<1) /* Doze */
|
||||
#define UCR1_UARTEN (1<<0) /* UART enabled */
|
||||
#define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */
|
||||
#define UCR2_IRTS (1<<14) /* Ignore RTS pin */
|
||||
#define UCR2_CTSC (1<<13) /* CTS pin control */
|
||||
#define UCR2_CTS (1<<12) /* Clear to send */
|
||||
#define UCR2_ESCEN (1<<11) /* Escape enable */
|
||||
#define UCR2_PREN (1<<8) /* Parity enable */
|
||||
#define UCR2_PROE (1<<7) /* Parity odd/even */
|
||||
#define UCR2_STPB (1<<6) /* Stop */
|
||||
#define UCR2_WS (1<<5) /* Word size */
|
||||
#define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */
|
||||
#define UCR2_TXEN (1<<2) /* Transmitter enabled */
|
||||
#define UCR2_RXEN (1<<1) /* Receiver enabled */
|
||||
#define UCR2_SRST (1<<0) /* SW reset */
|
||||
#define UCR3_DTREN (1<<13) /* DTR interrupt enable */
|
||||
#define UCR3_PARERREN (1<<12) /* Parity enable */
|
||||
#define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */
|
||||
#define UCR3_DSR (1<<10) /* Data set ready */
|
||||
#define UCR3_DCD (1<<9) /* Data carrier detect */
|
||||
#define UCR3_RI (1<<8) /* Ring indicator */
|
||||
#define UCR3_TIMEOUTEN (1<<7) /* Timeout interrupt enable */
|
||||
#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */
|
||||
#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */
|
||||
#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */
|
||||
#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz */
|
||||
#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz */
|
||||
#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */
|
||||
#define UCR3_BPEN (1<<0) /* Preset registers enable */
|
||||
#define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */
|
||||
#define UCR4_INVR (1<<9) /* Inverted infrared reception */
|
||||
#define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */
|
||||
#define UCR4_WKEN (1<<7) /* Wake interrupt enable */
|
||||
#define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */
|
||||
#define UCR4_IRSC (1<<5) /* IR special case */
|
||||
#define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */
|
||||
#define UCR4_BKEN (1<<2) /* Break condition interrupt enable */
|
||||
#define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */
|
||||
#define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */
|
||||
#define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */
|
||||
#define UFCR_RFDIV (7<<7) /* Reference freq divider mask */
|
||||
#define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */
|
||||
#define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */
|
||||
#define USR1_RTSS (1<<14) /* RTS pin status */
|
||||
#define USR1_TRDY (1<<13)/* Transmitter ready interrupt/dma flag */
|
||||
#define USR1_RTSD (1<<12) /* RTS delta */
|
||||
#define USR1_ESCF (1<<11) /* Escape seq interrupt flag */
|
||||
#define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */
|
||||
#define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */
|
||||
#define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */
|
||||
#define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */
|
||||
#define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */
|
||||
#define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */
|
||||
#define USR2_ADET (1<<15) /* Auto baud rate detect complete */
|
||||
#define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */
|
||||
#define USR2_DTRF (1<<13) /* DTR edge interrupt flag */
|
||||
#define USR2_IDLE (1<<12) /* Idle condition */
|
||||
#define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */
|
||||
#define USR2_WAKE (1<<7) /* Wake */
|
||||
#define USR2_RTSF (1<<4) /* RTS edge interrupt flag */
|
||||
#define USR2_TXDC (1<<3) /* Transmitter complete */
|
||||
#define USR2_BRCD (1<<2) /* Break condition */
|
||||
#define USR2_ORE (1<<1) /* Overrun error */
|
||||
#define USR2_RDR (1<<0) /* Recv data ready */
|
||||
#define UTS_FRCPERR (1<<13) /* Force parity error */
|
||||
#define UTS_LOOP (1<<12) /* Loop tx and rx */
|
||||
#define UTS_TXEMPTY (1<<6) /* TxFIFO empty */
|
||||
#define UTS_RXEMPTY (1<<5) /* RxFIFO empty */
|
||||
#define UTS_TXFULL (1<<4) /* TxFIFO full */
|
||||
#define UTS_RXFULL (1<<3) /* RxFIFO full */
|
||||
#define UTS_SOFTRST (1<<0) /* Software reset */
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
void serial_setbrg(void)
|
||||
{
|
||||
u32 clk = mxc_get_clock(MXC_UART_CLK);
|
||||
|
||||
if (!gd->baudrate)
|
||||
gd->baudrate = CONFIG_BAUDRATE;
|
||||
__REG(UART_PHYS + UFCR) = 0x4 << 7; /* divide input clock by 2 */
|
||||
__REG(UART_PHYS + UBIR) = 0xf;
|
||||
__REG(UART_PHYS + UBMR) = clk / (2 * gd->baudrate);
|
||||
}
|
||||
|
||||
int serial_getc(void)
|
||||
{
|
||||
while (__REG(UART_PHYS + UTS) & UTS_RXEMPTY)
|
||||
;
|
||||
return __REG(UART_PHYS + URXD);
|
||||
}
|
||||
|
||||
void serial_putc(const char c)
|
||||
{
|
||||
__REG(UART_PHYS + UTXD) = c;
|
||||
|
||||
/* wait for transmitter to be ready */
|
||||
while (!(__REG(UART_PHYS + UTS) & UTS_TXEMPTY))
|
||||
;
|
||||
|
||||
/* If \n, also do \r */
|
||||
if (c == '\n')
|
||||
serial_putc('\r');
|
||||
}
|
||||
|
||||
/*
|
||||
* Test whether a character is in the RX buffer
|
||||
*/
|
||||
int serial_tstc(void)
|
||||
{
|
||||
/* If receive fifo is empty, return false */
|
||||
if (__REG(UART_PHYS + UTS) & UTS_RXEMPTY)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void serial_puts(const char *s)
|
||||
{
|
||||
while (*s)
|
||||
serial_putc(*s++);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise the serial port with the given baudrate. The settings
|
||||
* are always 8 data bits, no parity, 1 stop bit, no start bits.
|
||||
*
|
||||
*/
|
||||
int serial_init(void)
|
||||
{
|
||||
__REG(UART_PHYS + UCR1) = 0x0;
|
||||
__REG(UART_PHYS + UCR2) = 0x0;
|
||||
|
||||
while (!(__REG(UART_PHYS + UCR2) & UCR2_SRST))
|
||||
;
|
||||
|
||||
__REG(UART_PHYS + UCR3) = 0x0704;
|
||||
__REG(UART_PHYS + UCR4) = 0x8000;
|
||||
__REG(UART_PHYS + UESC) = 0x002b;
|
||||
__REG(UART_PHYS + UTIM) = 0x0;
|
||||
|
||||
__REG(UART_PHYS + UTS) = 0x0;
|
||||
|
||||
serial_setbrg();
|
||||
|
||||
__REG(UART_PHYS + UCR2) =
|
||||
UCR2_WS | UCR2_IRTS | UCR2_RXEN | UCR2_TXEN | UCR2_SRST;
|
||||
|
||||
__REG(UART_PHYS + UCR1) = UCR1_UARTEN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MX51_UART */
|
||||
46
cpu/arm_cortexa8/omap3/Makefile
Normal file
46
cpu/arm_cortexa8/omap3/Makefile
Normal file
@ -0,0 +1,46 @@
|
||||
#
|
||||
# (C) Copyright 2000-2003
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@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
|
||||
|
||||
SOBJS := lowlevel_init.o
|
||||
COBJS := sys_info.o board.o clock.o interrupts.o mem.o syslib.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
344
cpu/arm_cortexa8/omap3/board.c
Normal file
344
cpu/arm_cortexa8/omap3/board.c
Normal file
@ -0,0 +1,344 @@
|
||||
/*
|
||||
*
|
||||
* Common board functions for OMAP3 based boards.
|
||||
*
|
||||
* (C) Copyright 2004-2008
|
||||
* Texas Instruments, <www.ti.com>
|
||||
*
|
||||
* Author :
|
||||
* Sunil Kumar <sunilsaini05@gmail.com>
|
||||
* Shashi Ranjan <shashiranjanmca05@gmail.com>
|
||||
*
|
||||
* Derived from Beagle Board and 3430 SDP code by
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Syed Mohammed Khasim <khasim@ti.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., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/arch/mem.h>
|
||||
|
||||
extern omap3_sysinfo sysinfo;
|
||||
|
||||
/******************************************************************************
|
||||
* Routine: delay
|
||||
* Description: spinning delay to use before udelay works
|
||||
*****************************************************************************/
|
||||
static inline void delay(unsigned long loops)
|
||||
{
|
||||
__asm__ volatile ("1:\n" "subs %0, %1, #1\n"
|
||||
"bne 1b":"=r" (loops):"0"(loops));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine: secure_unlock
|
||||
* Description: Setup security registers for access
|
||||
* (GP Device only)
|
||||
*****************************************************************************/
|
||||
void secure_unlock_mem(void)
|
||||
{
|
||||
pm_t *pm_rt_ape_base = (pm_t *)PM_RT_APE_BASE_ADDR_ARM;
|
||||
pm_t *pm_gpmc_base = (pm_t *)PM_GPMC_BASE_ADDR_ARM;
|
||||
pm_t *pm_ocm_ram_base = (pm_t *)PM_OCM_RAM_BASE_ADDR_ARM;
|
||||
pm_t *pm_iva2_base = (pm_t *)PM_IVA2_BASE_ADDR_ARM;
|
||||
sms_t *sms_base = (sms_t *)OMAP34XX_SMS_BASE;
|
||||
|
||||
/* Protection Module Register Target APE (PM_RT) */
|
||||
writel(UNLOCK_1, &pm_rt_ape_base->req_info_permission_1);
|
||||
writel(UNLOCK_1, &pm_rt_ape_base->read_permission_0);
|
||||
writel(UNLOCK_1, &pm_rt_ape_base->wirte_permission_0);
|
||||
writel(UNLOCK_2, &pm_rt_ape_base->addr_match_1);
|
||||
|
||||
writel(UNLOCK_3, &pm_gpmc_base->req_info_permission_0);
|
||||
writel(UNLOCK_3, &pm_gpmc_base->read_permission_0);
|
||||
writel(UNLOCK_3, &pm_gpmc_base->wirte_permission_0);
|
||||
|
||||
writel(UNLOCK_3, &pm_ocm_ram_base->req_info_permission_0);
|
||||
writel(UNLOCK_3, &pm_ocm_ram_base->read_permission_0);
|
||||
writel(UNLOCK_3, &pm_ocm_ram_base->wirte_permission_0);
|
||||
writel(UNLOCK_2, &pm_ocm_ram_base->addr_match_2);
|
||||
|
||||
/* IVA Changes */
|
||||
writel(UNLOCK_3, &pm_iva2_base->req_info_permission_0);
|
||||
writel(UNLOCK_3, &pm_iva2_base->read_permission_0);
|
||||
writel(UNLOCK_3, &pm_iva2_base->wirte_permission_0);
|
||||
|
||||
/* SDRC region 0 public */
|
||||
writel(UNLOCK_1, &sms_base->rg_att0);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine: secureworld_exit()
|
||||
* Description: If chip is EMU and boot type is external
|
||||
* configure secure registers and exit secure world
|
||||
* general use.
|
||||
*****************************************************************************/
|
||||
void secureworld_exit()
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
/* configrue non-secure access control register */
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c1, c1, 2":"=r"(i));
|
||||
/* enabling co-processor CP10 and CP11 accesses in NS world */
|
||||
__asm__ __volatile__("orr %0, %0, #0xC00":"=r"(i));
|
||||
/*
|
||||
* allow allocation of locked TLBs and L2 lines in NS world
|
||||
* allow use of PLE registers in NS world also
|
||||
*/
|
||||
__asm__ __volatile__("orr %0, %0, #0x70000":"=r"(i));
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c1, c1, 2":"=r"(i));
|
||||
|
||||
/* Enable ASA in ACR register */
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i));
|
||||
__asm__ __volatile__("orr %0, %0, #0x10":"=r"(i));
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i));
|
||||
|
||||
/* Exiting secure world */
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c1, c1, 0":"=r"(i));
|
||||
__asm__ __volatile__("orr %0, %0, #0x31":"=r"(i));
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c1, c1, 0":"=r"(i));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine: setup_auxcr()
|
||||
* Description: Write to AuxCR desired value using SMI.
|
||||
* general use.
|
||||
*****************************************************************************/
|
||||
void setup_auxcr()
|
||||
{
|
||||
unsigned long i;
|
||||
volatile unsigned int j;
|
||||
/* Save r0, r12 and restore them after usage */
|
||||
__asm__ __volatile__("mov %0, r12":"=r"(j));
|
||||
__asm__ __volatile__("mov %0, r0":"=r"(i));
|
||||
|
||||
/*
|
||||
* GP Device ROM code API usage here
|
||||
* r12 = AUXCR Write function and r0 value
|
||||
*/
|
||||
__asm__ __volatile__("mov r12, #0x3");
|
||||
__asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1");
|
||||
/* Enabling ASA */
|
||||
__asm__ __volatile__("orr r0, r0, #0x10");
|
||||
/* Enable L1NEON */
|
||||
__asm__ __volatile__("orr r0, r0, #1 << 5");
|
||||
/* SMI instruction to call ROM Code API */
|
||||
__asm__ __volatile__(".word 0xE1600070");
|
||||
__asm__ __volatile__("mov r0, %0":"=r"(i));
|
||||
__asm__ __volatile__("mov r12, %0":"=r"(j));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine: try_unlock_sram()
|
||||
* Description: If chip is GP/EMU(special) type, unlock the SRAM for
|
||||
* general use.
|
||||
*****************************************************************************/
|
||||
void try_unlock_memory()
|
||||
{
|
||||
int mode;
|
||||
int in_sdram = is_running_in_sdram();
|
||||
|
||||
/*
|
||||
* if GP device unlock device SRAM for general use
|
||||
* secure code breaks for Secure/Emulation device - HS/E/T
|
||||
*/
|
||||
mode = get_device_type();
|
||||
if (mode == GP_DEVICE)
|
||||
secure_unlock_mem();
|
||||
|
||||
/*
|
||||
* If device is EMU and boot is XIP external booting
|
||||
* Unlock firewalls and disable L2 and put chip
|
||||
* out of secure world
|
||||
*
|
||||
* Assuming memories are unlocked by the demon who put us in SDRAM
|
||||
*/
|
||||
if ((mode <= EMU_DEVICE) && (get_boot_type() == 0x1F)
|
||||
&& (!in_sdram)) {
|
||||
secure_unlock_mem();
|
||||
secureworld_exit();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine: s_init
|
||||
* Description: Does early system init of muxing and clocks.
|
||||
* - Called path is with SRAM stack.
|
||||
*****************************************************************************/
|
||||
void s_init(void)
|
||||
{
|
||||
int in_sdram = is_running_in_sdram();
|
||||
|
||||
watchdog_init();
|
||||
|
||||
try_unlock_memory();
|
||||
|
||||
/*
|
||||
* Right now flushing at low MPU speed.
|
||||
* Need to move after clock init
|
||||
*/
|
||||
v7_flush_dcache_all(get_device_type());
|
||||
#ifndef CONFIG_ICACHE_OFF
|
||||
icache_enable();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_L2_OFF
|
||||
l2cache_disable();
|
||||
#else
|
||||
l2cache_enable();
|
||||
#endif
|
||||
/*
|
||||
* Writing to AuxCR in U-boot using SMI for GP DEV
|
||||
* Currently SMI in Kernel on ES2 devices seems to have an issue
|
||||
* Once that is resolved, we can postpone this config to kernel
|
||||
*/
|
||||
if (get_device_type() == GP_DEVICE)
|
||||
setup_auxcr();
|
||||
|
||||
set_muxconf_regs();
|
||||
delay(100);
|
||||
|
||||
prcm_init();
|
||||
|
||||
per_clocks_enable();
|
||||
|
||||
if (!in_sdram)
|
||||
sdrc_init();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine: wait_for_command_complete
|
||||
* Description: Wait for posting to finish on watchdog
|
||||
*****************************************************************************/
|
||||
void wait_for_command_complete(watchdog_t *wd_base)
|
||||
{
|
||||
int pending = 1;
|
||||
do {
|
||||
pending = readl(&wd_base->wwps);
|
||||
} while (pending);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine: watchdog_init
|
||||
* Description: Shut down watch dogs
|
||||
*****************************************************************************/
|
||||
void watchdog_init(void)
|
||||
{
|
||||
watchdog_t *wd2_base = (watchdog_t *)WD2_BASE;
|
||||
prcm_t *prcm_base = (prcm_t *)PRCM_BASE;
|
||||
|
||||
/*
|
||||
* There are 3 watch dogs WD1=Secure, WD2=MPU, WD3=IVA. WD1 is
|
||||
* either taken care of by ROM (HS/EMU) or not accessible (GP).
|
||||
* We need to take care of WD2-MPU or take a PRCM reset. WD3
|
||||
* should not be running and does not generate a PRCM reset.
|
||||
*/
|
||||
|
||||
sr32(&prcm_base->fclken_wkup, 5, 1, 1);
|
||||
sr32(&prcm_base->iclken_wkup, 5, 1, 1);
|
||||
wait_on_value(ST_WDT2, 0x20, &prcm_base->idlest_wkup, 5);
|
||||
|
||||
writel(WD_UNLOCK1, &wd2_base->wspr);
|
||||
wait_for_command_complete(wd2_base);
|
||||
writel(WD_UNLOCK2, &wd2_base->wspr);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine: dram_init
|
||||
* Description: sets uboots idea of sdram size
|
||||
*****************************************************************************/
|
||||
int dram_init(void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
unsigned int size0 = 0, size1 = 0;
|
||||
u32 btype;
|
||||
|
||||
btype = get_board_type();
|
||||
|
||||
display_board_info(btype);
|
||||
|
||||
/*
|
||||
* If a second bank of DDR is attached to CS1 this is
|
||||
* where it can be started. Early init code will init
|
||||
* memory on CS0.
|
||||
*/
|
||||
if ((sysinfo.mtype == DDR_COMBO) || (sysinfo.mtype == DDR_STACKED)) {
|
||||
do_sdrc_init(CS1, NOT_EARLY);
|
||||
make_cs1_contiguous();
|
||||
}
|
||||
|
||||
size0 = get_sdr_cs_size(CS0);
|
||||
size1 = get_sdr_cs_size(CS1);
|
||||
|
||||
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
|
||||
gd->bd->bi_dram[0].size = size0;
|
||||
gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1);
|
||||
gd->bd->bi_dram[1].size = size1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Dummy function to handle errors for EABI incompatibility
|
||||
*****************************************************************************/
|
||||
void raise(void)
|
||||
{
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Dummy function to handle errors for EABI incompatibility
|
||||
*****************************************************************************/
|
||||
void abort(void)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NAND_OMAP_GPMC
|
||||
/******************************************************************************
|
||||
* OMAP3 specific command to switch between NAND HW and SW ecc
|
||||
*****************************************************************************/
|
||||
static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
goto usage;
|
||||
if (strncmp(argv[1], "hw", 2) == 0)
|
||||
omap_nand_switch_ecc(1);
|
||||
else if (strncmp(argv[1], "sw", 2) == 0)
|
||||
omap_nand_switch_ecc(0);
|
||||
else
|
||||
goto usage;
|
||||
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
printf ("Usage: nandecc %s\n", cmdtp->help);
|
||||
return 1;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
nandecc, 2, 1, do_switch_ecc,
|
||||
"nandecc - switch OMAP3 NAND ECC calculation algorithm\n",
|
||||
"[hw/sw] - Switch between NAND hardware (hw) or software (sw) ecc algorithm\n"
|
||||
);
|
||||
|
||||
#endif /* CONFIG_NAND_OMAP_GPMC */
|
||||
381
cpu/arm_cortexa8/omap3/clock.c
Normal file
381
cpu/arm_cortexa8/omap3/clock.c
Normal file
@ -0,0 +1,381 @@
|
||||
/*
|
||||
* (C) Copyright 2008
|
||||
* Texas Instruments, <www.ti.com>
|
||||
*
|
||||
* Author :
|
||||
* Manikandan Pillai <mani.pillai@ti.com>
|
||||
*
|
||||
* Derived from Beagle Board and OMAP3 SDP code by
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Syed Mohammed Khasim <khasim@ti.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/io.h>
|
||||
#include <asm/arch/clocks.h>
|
||||
#include <asm/arch/clocks_omap3.h>
|
||||
#include <asm/arch/mem.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <environment.h>
|
||||
#include <command.h>
|
||||
|
||||
/******************************************************************************
|
||||
* get_sys_clk_speed() - determine reference oscillator speed
|
||||
* based on known 32kHz clock and gptimer.
|
||||
*****************************************************************************/
|
||||
u32 get_osc_clk_speed(void)
|
||||
{
|
||||
u32 start, cstart, cend, cdiff, val;
|
||||
prcm_t *prcm_base = (prcm_t *)PRCM_BASE;
|
||||
prm_t *prm_base = (prm_t *)PRM_BASE;
|
||||
gptimer_t *gpt1_base = (gptimer_t *)OMAP34XX_GPT1;
|
||||
s32ktimer_t *s32k_base = (s32ktimer_t *)SYNC_32KTIMER_BASE;
|
||||
|
||||
val = readl(&prm_base->clksrc_ctrl);
|
||||
|
||||
/* If SYS_CLK is being divided by 2, remove for now */
|
||||
val = (val & (~SYSCLKDIV_2)) | SYSCLKDIV_1;
|
||||
writel(val, &prm_base->clksrc_ctrl);
|
||||
|
||||
/* enable timer2 */
|
||||
val = readl(&prcm_base->clksel_wkup) | CLKSEL_GPT1;
|
||||
|
||||
/* select sys_clk for GPT1 */
|
||||
writel(val, &prcm_base->clksel_wkup);
|
||||
|
||||
/* Enable I and F Clocks for GPT1 */
|
||||
val = readl(&prcm_base->iclken_wkup) | EN_GPT1 | EN_32KSYNC;
|
||||
writel(val, &prcm_base->iclken_wkup);
|
||||
val = readl(&prcm_base->fclken_wkup) | EN_GPT1;
|
||||
writel(val, &prcm_base->fclken_wkup);
|
||||
|
||||
writel(0, &gpt1_base->tldr); /* start counting at 0 */
|
||||
writel(GPT_EN, &gpt1_base->tclr); /* enable clock */
|
||||
|
||||
/* enable 32kHz source, determine sys_clk via gauging */
|
||||
|
||||
/* start time in 20 cycles */
|
||||
start = 20 + readl(&s32k_base->s32k_cr);
|
||||
|
||||
/* dead loop till start time */
|
||||
while (readl(&s32k_base->s32k_cr) < start);
|
||||
|
||||
/* get start sys_clk count */
|
||||
cstart = readl(&gpt1_base->tcrr);
|
||||
|
||||
/* wait for 40 cycles */
|
||||
while (readl(&s32k_base->s32k_cr) < (start + 20)) ;
|
||||
cend = readl(&gpt1_base->tcrr); /* get end sys_clk count */
|
||||
cdiff = cend - cstart; /* get elapsed ticks */
|
||||
|
||||
/* based on number of ticks assign speed */
|
||||
if (cdiff > 19000)
|
||||
return S38_4M;
|
||||
else if (cdiff > 15200)
|
||||
return S26M;
|
||||
else if (cdiff > 13000)
|
||||
return S24M;
|
||||
else if (cdiff > 9000)
|
||||
return S19_2M;
|
||||
else if (cdiff > 7600)
|
||||
return S13M;
|
||||
else
|
||||
return S12M;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* get_sys_clkin_sel() - returns the sys_clkin_sel field value based on
|
||||
* input oscillator clock frequency.
|
||||
*****************************************************************************/
|
||||
void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel)
|
||||
{
|
||||
switch(osc_clk) {
|
||||
case S38_4M:
|
||||
*sys_clkin_sel = 4;
|
||||
break;
|
||||
case S26M:
|
||||
*sys_clkin_sel = 3;
|
||||
break;
|
||||
case S19_2M:
|
||||
*sys_clkin_sel = 2;
|
||||
break;
|
||||
case S13M:
|
||||
*sys_clkin_sel = 1;
|
||||
break;
|
||||
case S12M:
|
||||
default:
|
||||
*sys_clkin_sel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* prcm_init() - inits clocks for PRCM as defined in clocks.h
|
||||
* called from SRAM, or Flash (using temp SRAM stack).
|
||||
*****************************************************************************/
|
||||
void prcm_init(void)
|
||||
{
|
||||
void (*f_lock_pll) (u32, u32, u32, u32);
|
||||
int xip_safe, p0, p1, p2, p3;
|
||||
u32 osc_clk = 0, sys_clkin_sel;
|
||||
u32 clk_index, sil_index;
|
||||
prm_t *prm_base = (prm_t *)PRM_BASE;
|
||||
prcm_t *prcm_base = (prcm_t *)PRCM_BASE;
|
||||
dpll_param *dpll_param_p;
|
||||
|
||||
f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start +
|
||||
SRAM_VECT_CODE);
|
||||
|
||||
xip_safe = is_running_in_sram();
|
||||
|
||||
/*
|
||||
* Gauge the input clock speed and find out the sys_clkin_sel
|
||||
* value corresponding to the input clock.
|
||||
*/
|
||||
osc_clk = get_osc_clk_speed();
|
||||
get_sys_clkin_sel(osc_clk, &sys_clkin_sel);
|
||||
|
||||
/* set input crystal speed */
|
||||
sr32(&prm_base->clksel, 0, 3, sys_clkin_sel);
|
||||
|
||||
/* If the input clock is greater than 19.2M always divide/2 */
|
||||
if (sys_clkin_sel > 2) {
|
||||
/* input clock divider */
|
||||
sr32(&prm_base->clksrc_ctrl, 6, 2, 2);
|
||||
clk_index = sys_clkin_sel / 2;
|
||||
} else {
|
||||
/* input clock divider */
|
||||
sr32(&prm_base->clksrc_ctrl, 6, 2, 1);
|
||||
clk_index = sys_clkin_sel;
|
||||
}
|
||||
|
||||
/*
|
||||
* The DPLL tables are defined according to sysclk value and
|
||||
* silicon revision. The clk_index value will be used to get
|
||||
* the values for that input sysclk from the DPLL param table
|
||||
* and sil_index will get the values for that SysClk for the
|
||||
* appropriate silicon rev.
|
||||
*/
|
||||
sil_index = get_cpu_rev() - 1;
|
||||
|
||||
/* Unlock MPU DPLL (slows things down, and needed later) */
|
||||
sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS);
|
||||
wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu, LDELAY);
|
||||
|
||||
/* Getting the base address of Core DPLL param table */
|
||||
dpll_param_p = (dpll_param *) get_core_dpll_param();
|
||||
|
||||
/* Moving it to the right sysclk and ES rev base */
|
||||
dpll_param_p = dpll_param_p + 3 * clk_index + sil_index;
|
||||
if (xip_safe) {
|
||||
/*
|
||||
* CORE DPLL
|
||||
* sr32(CM_CLKSEL2_EMU) set override to work when asleep
|
||||
*/
|
||||
sr32(&prcm_base->clken_pll, 0, 3, PLL_FAST_RELOCK_BYPASS);
|
||||
wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen,
|
||||
LDELAY);
|
||||
|
||||
/*
|
||||
* For OMAP3 ES1.0 Errata 1.50, default value directly doesn't
|
||||
* work. write another value and then default value.
|
||||
*/
|
||||
|
||||
/* m3x2 */
|
||||
sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2 + 1);
|
||||
/* m3x2 */
|
||||
sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2);
|
||||
/* Set M2 */
|
||||
sr32(&prcm_base->clksel1_pll, 27, 2, dpll_param_p->m2);
|
||||
/* Set M */
|
||||
sr32(&prcm_base->clksel1_pll, 16, 11, dpll_param_p->m);
|
||||
/* Set N */
|
||||
sr32(&prcm_base->clksel1_pll, 8, 7, dpll_param_p->n);
|
||||
/* 96M Src */
|
||||
sr32(&prcm_base->clksel1_pll, 6, 1, 0);
|
||||
/* ssi */
|
||||
sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV);
|
||||
/* fsusb */
|
||||
sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV);
|
||||
/* l4 */
|
||||
sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV);
|
||||
/* l3 */
|
||||
sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV);
|
||||
/* gfx */
|
||||
sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV);
|
||||
/* reset mgr */
|
||||
sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM);
|
||||
/* FREQSEL */
|
||||
sr32(&prcm_base->clken_pll, 4, 4, dpll_param_p->fsel);
|
||||
/* lock mode */
|
||||
sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK);
|
||||
|
||||
wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
|
||||
LDELAY);
|
||||
} else if (is_running_in_flash()) {
|
||||
/*
|
||||
* if running from flash, jump to small relocated code
|
||||
* area in SRAM.
|
||||
*/
|
||||
p0 = readl(&prcm_base->clken_pll);
|
||||
sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
|
||||
sr32(&p0, 4, 4, dpll_param_p->fsel); /* FREQSEL */
|
||||
|
||||
p1 = readl(&prcm_base->clksel1_pll);
|
||||
sr32(&p1, 27, 2, dpll_param_p->m2); /* Set M2 */
|
||||
sr32(&p1, 16, 11, dpll_param_p->m); /* Set M */
|
||||
sr32(&p1, 8, 7, dpll_param_p->n); /* Set N */
|
||||
sr32(&p1, 6, 1, 0); /* set source for 96M */
|
||||
|
||||
p2 = readl(&prcm_base->clksel_core);
|
||||
sr32(&p2, 8, 4, CORE_SSI_DIV); /* ssi */
|
||||
sr32(&p2, 4, 2, CORE_FUSB_DIV); /* fsusb */
|
||||
sr32(&p2, 2, 2, CORE_L4_DIV); /* l4 */
|
||||
sr32(&p2, 0, 2, CORE_L3_DIV); /* l3 */
|
||||
|
||||
p3 = (u32)&prcm_base->idlest_ckgen;
|
||||
|
||||
(*f_lock_pll) (p0, p1, p2, p3);
|
||||
}
|
||||
|
||||
/* PER DPLL */
|
||||
sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP);
|
||||
wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
|
||||
|
||||
/* Getting the base address to PER DPLL param table */
|
||||
|
||||
/* Set N */
|
||||
dpll_param_p = (dpll_param *) get_per_dpll_param();
|
||||
|
||||
/* Moving it to the right sysclk base */
|
||||
dpll_param_p = dpll_param_p + clk_index;
|
||||
|
||||
/*
|
||||
* Errata 1.50 Workaround for OMAP3 ES1.0 only
|
||||
* If using default divisors, write default divisor + 1
|
||||
* and then the actual divisor value
|
||||
*/
|
||||
sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2 + 1); /* set M6 */
|
||||
sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2); /* set M6 */
|
||||
sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2 + 1); /* set M5 */
|
||||
sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2); /* set M5 */
|
||||
sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2 + 1); /* set M4 */
|
||||
sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2); /* set M4 */
|
||||
sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2 + 1); /* set M3 */
|
||||
sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2); /* set M3 */
|
||||
sr32(&prcm_base->clksel3_pll, 0, 5, dpll_param_p->m2 + 1); /* set M2 */
|
||||
sr32(&prcm_base->clksel3_pll, 0, 5, dpll_param_p->m2); /* set M2 */
|
||||
/* Workaround end */
|
||||
|
||||
sr32(&prcm_base->clksel2_pll, 8, 11, dpll_param_p->m); /* set m */
|
||||
sr32(&prcm_base->clksel2_pll, 0, 7, dpll_param_p->n); /* set n */
|
||||
sr32(&prcm_base->clken_pll, 20, 4, dpll_param_p->fsel); /* FREQSEL */
|
||||
sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK); /* lock mode */
|
||||
wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
|
||||
|
||||
/* Getting the base address to MPU DPLL param table */
|
||||
dpll_param_p = (dpll_param *) get_mpu_dpll_param();
|
||||
|
||||
/* Moving it to the right sysclk and ES rev base */
|
||||
dpll_param_p = dpll_param_p + 3 * clk_index + sil_index;
|
||||
|
||||
/* MPU DPLL (unlocked already) */
|
||||
|
||||
/* Set M2 */
|
||||
sr32(&prcm_base->clksel2_pll_mpu, 0, 5, dpll_param_p->m2);
|
||||
/* Set M */
|
||||
sr32(&prcm_base->clksel1_pll_mpu, 8, 11, dpll_param_p->m);
|
||||
/* Set N */
|
||||
sr32(&prcm_base->clksel1_pll_mpu, 0, 7, dpll_param_p->n);
|
||||
/* FREQSEL */
|
||||
sr32(&prcm_base->clken_pll_mpu, 4, 4, dpll_param_p->fsel);
|
||||
/* lock mode */
|
||||
sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK);
|
||||
wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu, LDELAY);
|
||||
|
||||
/* Getting the base address to IVA DPLL param table */
|
||||
dpll_param_p = (dpll_param *) get_iva_dpll_param();
|
||||
|
||||
/* Moving it to the right sysclk and ES rev base */
|
||||
dpll_param_p = dpll_param_p + 3 * clk_index + sil_index;
|
||||
|
||||
/* IVA DPLL (set to 12*20=240MHz) */
|
||||
sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP);
|
||||
wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
|
||||
/* set M2 */
|
||||
sr32(&prcm_base->clksel2_pll_iva2, 0, 5, dpll_param_p->m2);
|
||||
/* set M */
|
||||
sr32(&prcm_base->clksel1_pll_iva2, 8, 11, dpll_param_p->m);
|
||||
/* set N */
|
||||
sr32(&prcm_base->clksel1_pll_iva2, 0, 7, dpll_param_p->n);
|
||||
/* FREQSEL */
|
||||
sr32(&prcm_base->clken_pll_iva2, 4, 4, dpll_param_p->fsel);
|
||||
/* lock mode */
|
||||
sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK);
|
||||
wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
|
||||
|
||||
/* Set up GPTimers to sys_clk source only */
|
||||
sr32(&prcm_base->clksel_per, 0, 8, 0xff);
|
||||
sr32(&prcm_base->clksel_wkup, 0, 1, 1);
|
||||
|
||||
sdelay(5000);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* peripheral_enable() - Enable the clks & power for perifs (GPT2, UART1,...)
|
||||
*****************************************************************************/
|
||||
void per_clocks_enable(void)
|
||||
{
|
||||
prcm_t *prcm_base = (prcm_t *)PRCM_BASE;
|
||||
|
||||
/* Enable GP2 timer. */
|
||||
sr32(&prcm_base->clksel_per, 0, 1, 0x1); /* GPT2 = sys clk */
|
||||
sr32(&prcm_base->iclken_per, 3, 1, 0x1); /* ICKen GPT2 */
|
||||
sr32(&prcm_base->fclken_per, 3, 1, 0x1); /* FCKen GPT2 */
|
||||
|
||||
#ifdef CONFIG_SYS_NS16550
|
||||
/* Enable UART1 clocks */
|
||||
sr32(&prcm_base->fclken1_core, 13, 1, 0x1);
|
||||
sr32(&prcm_base->iclken1_core, 13, 1, 0x1);
|
||||
|
||||
/* UART 3 Clocks */
|
||||
sr32(&prcm_base->fclken_per, 11, 1, 0x1);
|
||||
sr32(&prcm_base->iclken_per, 11, 1, 0x1);
|
||||
#endif
|
||||
#ifdef CONFIG_DRIVER_OMAP34XX_I2C
|
||||
/* Turn on all 3 I2C clocks */
|
||||
sr32(&prcm_base->fclken1_core, 15, 3, 0x7);
|
||||
sr32(&prcm_base->iclken1_core, 15, 3, 0x7); /* I2C1,2,3 = on */
|
||||
#endif
|
||||
/* Enable the ICLK for 32K Sync Timer as its used in udelay */
|
||||
sr32(&prcm_base->iclken_wkup, 2, 1, 0x1);
|
||||
|
||||
sr32(&prcm_base->fclken_iva2, 0, 32, FCK_IVA2_ON);
|
||||
sr32(&prcm_base->fclken1_core, 0, 32, FCK_CORE1_ON);
|
||||
sr32(&prcm_base->iclken1_core, 0, 32, ICK_CORE1_ON);
|
||||
sr32(&prcm_base->iclken2_core, 0, 32, ICK_CORE2_ON);
|
||||
sr32(&prcm_base->fclken_wkup, 0, 32, FCK_WKUP_ON);
|
||||
sr32(&prcm_base->iclken_wkup, 0, 32, ICK_WKUP_ON);
|
||||
sr32(&prcm_base->fclken_dss, 0, 32, FCK_DSS_ON);
|
||||
sr32(&prcm_base->iclken_dss, 0, 32, ICK_DSS_ON);
|
||||
sr32(&prcm_base->fclken_cam, 0, 32, FCK_CAM_ON);
|
||||
sr32(&prcm_base->iclken_cam, 0, 32, ICK_CAM_ON);
|
||||
sr32(&prcm_base->fclken_per, 0, 32, FCK_PER_ON);
|
||||
sr32(&prcm_base->iclken_per, 0, 32, ICK_PER_ON);
|
||||
|
||||
sdelay(1000);
|
||||
}
|
||||
36
cpu/arm_cortexa8/omap3/config.mk
Normal file
36
cpu/arm_cortexa8/omap3/config.mk
Normal file
@ -0,0 +1,36 @@
|
||||
#
|
||||
# (C) Copyright 2002
|
||||
# Gary Jennejohn, DENX Software Engineering, <gj@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
|
||||
#
|
||||
PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
|
||||
-msoft-float
|
||||
|
||||
# Make ARMv5 to allow more compilers to work, even though its v7a.
|
||||
PLATFORM_CPPFLAGS += -march=armv5
|
||||
# =========================================================================
|
||||
#
|
||||
# Supply options according to compiler version
|
||||
#
|
||||
# =========================================================================
|
||||
PLATFORM_CPPFLAGS +=$(call cc-option)
|
||||
PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
|
||||
PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,\
|
||||
$(call cc-option,-malignment-traps,))
|
||||
297
cpu/arm_cortexa8/omap3/interrupts.c
Normal file
297
cpu/arm_cortexa8/omap3/interrupts.c
Normal file
@ -0,0 +1,297 @@
|
||||
/*
|
||||
* (C) Copyright 2008
|
||||
* Texas Instruments
|
||||
*
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Syed Moahmmed Khasim <khasim@ti.com>
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
* Alex Zuepke <azu@sysgo.de>
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Gary Jennejohn, DENX Software Engineering, <gj@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 <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/proc-armv/ptrace.h>
|
||||
|
||||
#define TIMER_LOAD_VAL 0
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
/* enable IRQ interrupts */
|
||||
void enable_interrupts(void)
|
||||
{
|
||||
unsigned long temp;
|
||||
__asm__ __volatile__("mrs %0, cpsr\n"
|
||||
"bic %0, %0, #0x80\n" "msr cpsr_c, %0":"=r"(temp)
|
||||
::"memory");
|
||||
}
|
||||
|
||||
/*
|
||||
* disable IRQ/FIQ interrupts
|
||||
* returns true if interrupts had been enabled before we disabled them
|
||||
*/
|
||||
int disable_interrupts(void)
|
||||
{
|
||||
unsigned long old, temp;
|
||||
__asm__ __volatile__("mrs %0, cpsr\n"
|
||||
"orr %1, %0, #0xc0\n"
|
||||
"msr cpsr_c, %1":"=r"(old), "=r"(temp)
|
||||
::"memory");
|
||||
return (old & 0x80) == 0;
|
||||
}
|
||||
#else
|
||||
void enable_interrupts(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int disable_interrupts(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void bad_mode(void)
|
||||
{
|
||||
panic("Resetting CPU ...\n");
|
||||
reset_cpu(0);
|
||||
}
|
||||
|
||||
void show_regs(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long flags;
|
||||
const char *processor_modes[] = {
|
||||
"USER_26", "FIQ_26", "IRQ_26", "SVC_26",
|
||||
"UK4_26", "UK5_26", "UK6_26", "UK7_26",
|
||||
"UK8_26", "UK9_26", "UK10_26", "UK11_26",
|
||||
"UK12_26", "UK13_26", "UK14_26", "UK15_26",
|
||||
"USER_32", "FIQ_32", "IRQ_32", "SVC_32",
|
||||
"UK4_32", "UK5_32", "UK6_32", "ABT_32",
|
||||
"UK8_32", "UK9_32", "UK10_32", "UND_32",
|
||||
"UK12_32", "UK13_32", "UK14_32", "SYS_32",
|
||||
};
|
||||
|
||||
flags = condition_codes(regs);
|
||||
|
||||
printf("pc : [<%08lx>] lr : [<%08lx>]\n"
|
||||
"sp : %08lx ip : %08lx fp : %08lx\n",
|
||||
instruction_pointer(regs),
|
||||
regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
|
||||
printf("r10: %08lx r9 : %08lx r8 : %08lx\n",
|
||||
regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
|
||||
printf("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
|
||||
regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
|
||||
printf("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
|
||||
regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
|
||||
printf("Flags: %c%c%c%c",
|
||||
flags & CC_N_BIT ? 'N' : 'n',
|
||||
flags & CC_Z_BIT ? 'Z' : 'z',
|
||||
flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
|
||||
printf(" IRQs %s FIQs %s Mode %s%s\n",
|
||||
interrupts_enabled(regs) ? "on" : "off",
|
||||
fast_interrupts_enabled(regs) ? "on" : "off",
|
||||
processor_modes[processor_mode(regs)],
|
||||
thumb_mode(regs) ? " (T)" : "");
|
||||
}
|
||||
|
||||
void do_undefined_instruction(struct pt_regs *pt_regs)
|
||||
{
|
||||
printf("undefined instruction\n");
|
||||
show_regs(pt_regs);
|
||||
bad_mode();
|
||||
}
|
||||
|
||||
void do_software_interrupt(struct pt_regs *pt_regs)
|
||||
{
|
||||
printf("software interrupt\n");
|
||||
show_regs(pt_regs);
|
||||
bad_mode();
|
||||
}
|
||||
|
||||
void do_prefetch_abort(struct pt_regs *pt_regs)
|
||||
{
|
||||
printf("prefetch abort\n");
|
||||
show_regs(pt_regs);
|
||||
bad_mode();
|
||||
}
|
||||
|
||||
void do_data_abort(struct pt_regs *pt_regs)
|
||||
{
|
||||
printf("data abort\n");
|
||||
show_regs(pt_regs);
|
||||
bad_mode();
|
||||
}
|
||||
|
||||
void do_not_used(struct pt_regs *pt_regs)
|
||||
{
|
||||
printf("not used\n");
|
||||
show_regs(pt_regs);
|
||||
bad_mode();
|
||||
}
|
||||
|
||||
void do_fiq(struct pt_regs *pt_regs)
|
||||
{
|
||||
printf("fast interrupt request\n");
|
||||
show_regs(pt_regs);
|
||||
bad_mode();
|
||||
}
|
||||
|
||||
void do_irq(struct pt_regs *pt_regs)
|
||||
{
|
||||
printf("interrupt request\n");
|
||||
show_regs(pt_regs);
|
||||
bad_mode();
|
||||
}
|
||||
|
||||
|
||||
static ulong timestamp;
|
||||
static ulong lastinc;
|
||||
static gptimer_t *timer_base = (gptimer_t *)CONFIG_SYS_TIMERBASE;
|
||||
|
||||
/* nothing really to do with interrupts, just starts up a counter. */
|
||||
int interrupt_init(void)
|
||||
{
|
||||
/* start the counter ticking up, reload value on overflow */
|
||||
writel(TIMER_LOAD_VAL, &timer_base->tldr);
|
||||
/* enable timer */
|
||||
writel((CONFIG_SYS_PVT << 2) | TCLR_PRE | TCLR_AR | TCLR_ST,
|
||||
&timer_base->tclr);
|
||||
|
||||
reset_timer_masked(); /* init the timestamp and lastinc value */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* timer without interrupts
|
||||
*/
|
||||
void reset_timer(void)
|
||||
{
|
||||
reset_timer_masked();
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return get_timer_masked() - base;
|
||||
}
|
||||
|
||||
void set_timer(ulong t)
|
||||
{
|
||||
timestamp = t;
|
||||
}
|
||||
|
||||
/* delay x useconds AND perserve advance timstamp value */
|
||||
void udelay(unsigned long usec)
|
||||
{
|
||||
ulong tmo, tmp;
|
||||
|
||||
/* if "big" number, spread normalization to seconds */
|
||||
if (usec >= 1000) {
|
||||
/* if "big" number, spread normalization to seconds */
|
||||
tmo = usec / 1000;
|
||||
/* find number of "ticks" to wait to achieve target */
|
||||
tmo *= CONFIG_SYS_HZ;
|
||||
tmo /= 1000; /* finish normalize. */
|
||||
} else {/* else small number, don't kill it prior to HZ multiply */
|
||||
tmo = usec * CONFIG_SYS_HZ;
|
||||
tmo /= (1000 * 1000);
|
||||
}
|
||||
|
||||
tmp = get_timer(0); /* get current timestamp */
|
||||
/* if setting this forward will roll time stamp */
|
||||
if ((tmo + tmp + 1) < tmp)
|
||||
/* reset "advancing" timestamp to 0, set lastinc value */
|
||||
reset_timer_masked();
|
||||
else
|
||||
tmo += tmp; /* else, set advancing stamp wake up time */
|
||||
while (get_timer_masked() < tmo) /* loop till event */
|
||||
/*NOP*/;
|
||||
}
|
||||
|
||||
void reset_timer_masked(void)
|
||||
{
|
||||
/* reset time, capture current incrementer value time */
|
||||
lastinc = readl(&timer_base->tcrr);
|
||||
timestamp = 0; /* start "advancing" time stamp from 0 */
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
ulong now = readl(&timer_base->tcrr); /* current tick value */
|
||||
|
||||
if (now >= lastinc) /* normal mode (non roll) */
|
||||
/* move stamp fordward with absoulte diff ticks */
|
||||
timestamp += (now - lastinc);
|
||||
else /* we have rollover of incrementer */
|
||||
timestamp += (0xFFFFFFFF - lastinc) + now;
|
||||
lastinc = now;
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/* waits specified delay value and resets timestamp */
|
||||
void udelay_masked(unsigned long usec)
|
||||
{
|
||||
ulong tmo;
|
||||
ulong endtime;
|
||||
signed long diff;
|
||||
|
||||
/* if "big" number, spread normalization to seconds */
|
||||
if (usec >= 1000) {
|
||||
/* start to normalize for usec to ticks per sec */
|
||||
tmo = usec / 1000;
|
||||
/* find number of "ticks" to wait to achieve target */
|
||||
tmo *= CONFIG_SYS_HZ;
|
||||
tmo /= 1000; /* finish normalize. */
|
||||
} else { /* else small number, */
|
||||
/* don't kill it prior to HZ multiply */
|
||||
tmo = usec * CONFIG_SYS_HZ;
|
||||
tmo /= (1000 * 1000);
|
||||
}
|
||||
endtime = get_timer_masked() + tmo;
|
||||
|
||||
do {
|
||||
ulong now = get_timer_masked();
|
||||
diff = endtime - now;
|
||||
} while (diff >= 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
ulong tbclk;
|
||||
tbclk = CONFIG_SYS_HZ;
|
||||
return tbclk;
|
||||
}
|
||||
361
cpu/arm_cortexa8/omap3/lowlevel_init.S
Normal file
361
cpu/arm_cortexa8/omap3/lowlevel_init.S
Normal file
@ -0,0 +1,361 @@
|
||||
/*
|
||||
* Board specific setup info
|
||||
*
|
||||
* (C) Copyright 2008
|
||||
* Texas Instruments, <www.ti.com>
|
||||
*
|
||||
* Initial Code by:
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Syed Mohammed Khasim <khasim@ti.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., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <version.h>
|
||||
#include <asm/arch/mem.h>
|
||||
#include <asm/arch/clocks_omap3.h>
|
||||
|
||||
_TEXT_BASE:
|
||||
.word TEXT_BASE /* sdram load addr from config.mk */
|
||||
|
||||
#if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_NAND_BOOT)
|
||||
/**************************************************************************
|
||||
* cpy_clk_code: relocates clock code into SRAM where its safer to execute
|
||||
* R1 = SRAM destination address.
|
||||
*************************************************************************/
|
||||
.global cpy_clk_code
|
||||
cpy_clk_code:
|
||||
/* Copy DPLL code into SRAM */
|
||||
adr r0, go_to_speed /* get addr of clock setting code */
|
||||
mov r2, #384 /* r2 size to copy (div by 32 bytes) */
|
||||
mov r1, r1 /* r1 <- dest address (passed in) */
|
||||
add r2, r2, r0 /* r2 <- source end address */
|
||||
next2:
|
||||
ldmia r0!, {r3 - r10} /* copy from source address [r0] */
|
||||
stmia r1!, {r3 - r10} /* copy to target address [r1] */
|
||||
cmp r0, r2 /* until source end address [r2] */
|
||||
bne next2
|
||||
mov pc, lr /* back to caller */
|
||||
|
||||
/* ***************************************************************************
|
||||
* go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed
|
||||
* -executed from SRAM.
|
||||
* R0 = CM_CLKEN_PLL-bypass value
|
||||
* R1 = CM_CLKSEL1_PLL-m, n, and divider values
|
||||
* R2 = CM_CLKSEL_CORE-divider values
|
||||
* R3 = CM_IDLEST_CKGEN - addr dpll lock wait
|
||||
*
|
||||
* Note: If core unlocks/relocks and SDRAM is running fast already it gets
|
||||
* confused. A reset of the controller gets it back. Taking away its
|
||||
* L3 when its not in self refresh seems bad for it. Normally, this
|
||||
* code runs from flash before SDR is init so that should be ok.
|
||||
****************************************************************************/
|
||||
.global go_to_speed
|
||||
go_to_speed:
|
||||
stmfd sp!, {r4 - r6}
|
||||
|
||||
/* move into fast relock bypass */
|
||||
ldr r4, pll_ctl_add
|
||||
str r0, [r4]
|
||||
wait1:
|
||||
ldr r5, [r3] /* get status */
|
||||
and r5, r5, #0x1 /* isolate core status */
|
||||
cmp r5, #0x1 /* still locked? */
|
||||
beq wait1 /* if lock, loop */
|
||||
|
||||
/* set new dpll dividers _after_ in bypass */
|
||||
ldr r5, pll_div_add1
|
||||
str r1, [r5] /* set m, n, m2 */
|
||||
ldr r5, pll_div_add2
|
||||
str r2, [r5] /* set l3/l4/.. dividers*/
|
||||
ldr r5, pll_div_add3 /* wkup */
|
||||
ldr r2, pll_div_val3 /* rsm val */
|
||||
str r2, [r5]
|
||||
ldr r5, pll_div_add4 /* gfx */
|
||||
ldr r2, pll_div_val4
|
||||
str r2, [r5]
|
||||
ldr r5, pll_div_add5 /* emu */
|
||||
ldr r2, pll_div_val5
|
||||
str r2, [r5]
|
||||
|
||||
/* now prepare GPMC (flash) for new dpll speed */
|
||||
/* flash needs to be stable when we jump back to it */
|
||||
ldr r5, flash_cfg3_addr
|
||||
ldr r2, flash_cfg3_val
|
||||
str r2, [r5]
|
||||
ldr r5, flash_cfg4_addr
|
||||
ldr r2, flash_cfg4_val
|
||||
str r2, [r5]
|
||||
ldr r5, flash_cfg5_addr
|
||||
ldr r2, flash_cfg5_val
|
||||
str r2, [r5]
|
||||
ldr r5, flash_cfg1_addr
|
||||
ldr r2, [r5]
|
||||
orr r2, r2, #0x3 /* up gpmc divider */
|
||||
str r2, [r5]
|
||||
|
||||
/* lock DPLL3 and wait a bit */
|
||||
orr r0, r0, #0x7 /* set up for lock mode */
|
||||
str r0, [r4] /* lock */
|
||||
nop /* ARM slow at this point working at sys_clk */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
wait2:
|
||||
ldr r5, [r3] /* get status */
|
||||
and r5, r5, #0x1 /* isolate core status */
|
||||
cmp r5, #0x1 /* still locked? */
|
||||
bne wait2 /* if lock, loop */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
ldmfd sp!, {r4 - r6}
|
||||
mov pc, lr /* back to caller, locked */
|
||||
|
||||
_go_to_speed: .word go_to_speed
|
||||
|
||||
/* these constants need to be close for PIC code */
|
||||
/* The Nor has to be in the Flash Base CS0 for this condition to happen */
|
||||
flash_cfg1_addr:
|
||||
.word (GPMC_CONFIG_CS0 + GPMC_CONFIG1)
|
||||
flash_cfg3_addr:
|
||||
.word (GPMC_CONFIG_CS0 + GPMC_CONFIG3)
|
||||
flash_cfg3_val:
|
||||
.word STNOR_GPMC_CONFIG3
|
||||
flash_cfg4_addr:
|
||||
.word (GPMC_CONFIG_CS0 + GPMC_CONFIG4)
|
||||
flash_cfg4_val:
|
||||
.word STNOR_GPMC_CONFIG4
|
||||
flash_cfg5_val:
|
||||
.word STNOR_GPMC_CONFIG5
|
||||
flash_cfg5_addr:
|
||||
.word (GPMC_CONFIG_CS0 + GPMC_CONFIG5)
|
||||
pll_ctl_add:
|
||||
.word CM_CLKEN_PLL
|
||||
pll_div_add1:
|
||||
.word CM_CLKSEL1_PLL
|
||||
pll_div_add2:
|
||||
.word CM_CLKSEL_CORE
|
||||
pll_div_add3:
|
||||
.word CM_CLKSEL_WKUP
|
||||
pll_div_val3:
|
||||
.word (WKUP_RSM << 1)
|
||||
pll_div_add4:
|
||||
.word CM_CLKSEL_GFX
|
||||
pll_div_val4:
|
||||
.word (GFX_DIV << 0)
|
||||
pll_div_add5:
|
||||
.word CM_CLKSEL1_EMU
|
||||
pll_div_val5:
|
||||
.word CLSEL1_EMU_VAL
|
||||
|
||||
#endif
|
||||
|
||||
.globl lowlevel_init
|
||||
lowlevel_init:
|
||||
ldr sp, SRAM_STACK
|
||||
str ip, [sp] /* stash old link register */
|
||||
mov ip, lr /* save link reg across call */
|
||||
bl s_init /* go setup pll, mux, memory */
|
||||
ldr ip, [sp] /* restore save ip */
|
||||
mov lr, ip /* restore link reg */
|
||||
|
||||
/* back to arch calling code */
|
||||
mov pc, lr
|
||||
|
||||
/* the literal pools origin */
|
||||
.ltorg
|
||||
|
||||
REG_CONTROL_STATUS:
|
||||
.word CONTROL_STATUS
|
||||
SRAM_STACK:
|
||||
.word LOW_LEVEL_SRAM_STACK
|
||||
|
||||
/* DPLL(1-4) PARAM TABLES */
|
||||
|
||||
/*
|
||||
* Each of the tables has M, N, FREQSEL, M2 values defined for nominal
|
||||
* OPP (1.2V). The fields are defined according to dpll_param struct (clock.c).
|
||||
* The values are defined for all possible sysclk and for ES1 and ES2.
|
||||
*/
|
||||
|
||||
mpu_dpll_param:
|
||||
/* 12MHz */
|
||||
/* ES1 */
|
||||
.word MPU_M_12_ES1, MPU_N_12_ES1, MPU_FSEL_12_ES1, MPU_M2_12_ES1
|
||||
/* ES2 */
|
||||
.word MPU_M_12_ES2, MPU_N_12_ES2, MPU_FSEL_12_ES2, MPU_M2_ES2
|
||||
/* 3410 */
|
||||
.word MPU_M_12, MPU_N_12, MPU_FSEL_12, MPU_M2_12
|
||||
|
||||
/* 13MHz */
|
||||
/* ES1 */
|
||||
.word MPU_M_13_ES1, MPU_N_13_ES1, MPU_FSEL_13_ES1, MPU_M2_13_ES1
|
||||
/* ES2 */
|
||||
.word MPU_M_13_ES2, MPU_N_13_ES2, MPU_FSEL_13_ES2, MPU_M2_13_ES2
|
||||
/* 3410 */
|
||||
.word MPU_M_13, MPU_N_13, MPU_FSEL_13, MPU_M2_13
|
||||
|
||||
/* 19.2MHz */
|
||||
/* ES1 */
|
||||
.word MPU_M_19P2_ES1, MPU_N_19P2_ES1, MPU_FSEL_19P2_ES1, MPU_M2_19P2_ES1
|
||||
/* ES2 */
|
||||
.word MPU_M_19P2_ES2, MPU_N_19P2_ES2, MPU_FSEL_19P2_ES2, MPU_M2_19P2_ES2
|
||||
/* 3410 */
|
||||
.word MPU_M_19P2, MPU_N_19P2, MPU_FSEL_19P2, MPU_M2_19P2
|
||||
|
||||
/* 26MHz */
|
||||
/* ES1 */
|
||||
.word MPU_M_26_ES1, MPU_N_26_ES1, MPU_FSEL_26_ES1, MPU_M2_26_ES1
|
||||
/* ES2 */
|
||||
.word MPU_M_26_ES2, MPU_N_26_ES2, MPU_FSEL_26_ES2, MPU_M2_26_ES2
|
||||
/* 3410 */
|
||||
.word MPU_M_26, MPU_N_26, MPU_FSEL_26, MPU_M2_26
|
||||
|
||||
/* 38.4MHz */
|
||||
/* ES1 */
|
||||
.word MPU_M_38P4_ES1, MPU_N_38P4_ES1, MPU_FSEL_38P4_ES1, MPU_M2_38P4_ES1
|
||||
/* ES2 */
|
||||
.word MPU_M_38P4_ES2, MPU_N_38P4_ES2, MPU_FSEL_38P4_ES2, MPU_M2_38P4_ES2
|
||||
/* 3410 */
|
||||
.word MPU_M_38P4, MPU_N_38P4, MPU_FSEL_38P4, MPU_M2_38P4
|
||||
|
||||
|
||||
.globl get_mpu_dpll_param
|
||||
get_mpu_dpll_param:
|
||||
adr r0, mpu_dpll_param
|
||||
mov pc, lr
|
||||
|
||||
iva_dpll_param:
|
||||
/* 12MHz */
|
||||
/* ES1 */
|
||||
.word IVA_M_12_ES1, IVA_N_12_ES1, IVA_FSEL_12_ES1, IVA_M2_12_ES1
|
||||
/* ES2 */
|
||||
.word IVA_M_12_ES2, IVA_N_12_ES2, IVA_FSEL_12_ES2, IVA_M2_12_ES2
|
||||
/* 3410 */
|
||||
.word IVA_M_12, IVA_N_12, IVA_FSEL_12, IVA_M2_12
|
||||
|
||||
/* 13MHz */
|
||||
/* ES1 */
|
||||
.word IVA_M_13_ES1, IVA_N_13_ES1, IVA_FSEL_13_ES1, IVA_M2_13_ES1
|
||||
/* ES2 */
|
||||
.word IVA_M_13_ES2, IVA_N_13_ES2, IVA_FSEL_13_ES2, IVA_M2_13_ES2
|
||||
/* 3410 */
|
||||
.word IVA_M_13, IVA_N_13, IVA_FSEL_13, IVA_M2_13
|
||||
|
||||
/* 19.2MHz */
|
||||
/* ES1 */
|
||||
.word IVA_M_19P2_ES1, IVA_N_19P2_ES1, IVA_FSEL_19P2_ES1, IVA_M2_19P2_ES1
|
||||
/* ES2 */
|
||||
.word IVA_M_19P2_ES2, IVA_N_19P2_ES2, IVA_FSEL_19P2_ES2, IVA_M2_19P2_ES2
|
||||
/* 3410 */
|
||||
.word IVA_M_19P2, IVA_N_19P2, IVA_FSEL_19P2, IVA_M2_19P2
|
||||
|
||||
/* 26MHz */
|
||||
/* ES1 */
|
||||
.word IVA_M_26_ES1, IVA_N_26_ES1, IVA_FSEL_26_ES1, IVA_M2_26_ES1
|
||||
/* ES2 */
|
||||
.word IVA_M_26_ES2, IVA_N_26_ES2, IVA_FSEL_26_ES2, IVA_M2_26_ES2
|
||||
/* 3410 */
|
||||
.word IVA_M_26, IVA_N_26, IVA_FSEL_26, IVA_M2_26
|
||||
|
||||
/* 38.4MHz */
|
||||
/* ES1 */
|
||||
.word IVA_M_38P4_ES1, IVA_N_38P4_ES1, IVA_FSEL_38P4_ES1, IVA_M2_38P4_ES1
|
||||
/* ES2 */
|
||||
.word IVA_M_38P4_ES2, IVA_N_38P4_ES2, IVA_FSEL_38P4_ES2, IVA_M2_38P4_ES2
|
||||
/* 3410 */
|
||||
.word IVA_M_38P4, IVA_N_38P4, IVA_FSEL_38P4, IVA_M2_38P4
|
||||
|
||||
|
||||
.globl get_iva_dpll_param
|
||||
get_iva_dpll_param:
|
||||
adr r0, iva_dpll_param
|
||||
mov pc, lr
|
||||
|
||||
/* Core DPLL targets for L3 at 166 & L133 */
|
||||
core_dpll_param:
|
||||
/* 12MHz */
|
||||
/* ES1 */
|
||||
.word CORE_M_12_ES1, CORE_N_12_ES1, CORE_FSL_12_ES1, CORE_M2_12_ES1
|
||||
/* ES2 */
|
||||
.word CORE_M_12, CORE_N_12, CORE_FSEL_12, CORE_M2_12
|
||||
/* 3410 */
|
||||
.word CORE_M_12, CORE_N_12, CORE_FSEL_12, CORE_M2_12
|
||||
|
||||
/* 13MHz */
|
||||
/* ES1 */
|
||||
.word CORE_M_13_ES1, CORE_N_13_ES1, CORE_FSL_13_ES1, CORE_M2_13_ES1
|
||||
/* ES2 */
|
||||
.word CORE_M_13, CORE_N_13, CORE_FSEL_13, CORE_M2_13
|
||||
/* 3410 */
|
||||
.word CORE_M_13, CORE_N_13, CORE_FSEL_13, CORE_M2_13
|
||||
|
||||
/* 19.2MHz */
|
||||
/* ES1 */
|
||||
.word CORE_M_19P2_ES1, CORE_N_19P2_ES1, CORE_FSL_19P2_ES1, CORE_M2_19P2_ES1
|
||||
/* ES2 */
|
||||
.word CORE_M_19P2, CORE_N_19P2, CORE_FSEL_19P2, CORE_M2_19P2
|
||||
/* 3410 */
|
||||
.word CORE_M_19P2, CORE_N_19P2, CORE_FSEL_19P2, CORE_M2_19P2
|
||||
|
||||
/* 26MHz */
|
||||
/* ES1 */
|
||||
.word CORE_M_26_ES1, CORE_N_26_ES1, CORE_FSL_26_ES1, CORE_M2_26_ES1
|
||||
/* ES2 */
|
||||
.word CORE_M_26, CORE_N_26, CORE_FSEL_26, CORE_M2_26
|
||||
/* 3410 */
|
||||
.word CORE_M_26, CORE_N_26, CORE_FSEL_26, CORE_M2_26
|
||||
|
||||
/* 38.4MHz */
|
||||
/* ES1 */
|
||||
.word CORE_M_38P4_ES1, CORE_N_38P4_ES1, CORE_FSL_38P4_ES1, CORE_M2_38P4_ES1
|
||||
/* ES2 */
|
||||
.word CORE_M_38P4, CORE_N_38P4, CORE_FSEL_38P4, CORE_M2_38P4
|
||||
/* 3410 */
|
||||
.word CORE_M_38P4, CORE_N_38P4, CORE_FSEL_38P4, CORE_M2_38P4
|
||||
|
||||
.globl get_core_dpll_param
|
||||
get_core_dpll_param:
|
||||
adr r0, core_dpll_param
|
||||
mov pc, lr
|
||||
|
||||
/* PER DPLL values are same for both ES1 and ES2 */
|
||||
per_dpll_param:
|
||||
/* 12MHz */
|
||||
.word PER_M_12, PER_N_12, PER_FSEL_12, PER_M2_12
|
||||
|
||||
/* 13MHz */
|
||||
.word PER_M_13, PER_N_13, PER_FSEL_13, PER_M2_13
|
||||
|
||||
/* 19.2MHz */
|
||||
.word PER_M_19P2, PER_N_19P2, PER_FSEL_19P2, PER_M2_19P2
|
||||
|
||||
/* 26MHz */
|
||||
.word PER_M_26, PER_N_26, PER_FSEL_26, PER_M2_26
|
||||
|
||||
/* 38.4MHz */
|
||||
.word PER_M_38P4, PER_N_38P4, PER_FSEL_38P4, PER_M2_38P4
|
||||
|
||||
.globl get_per_dpll_param
|
||||
get_per_dpll_param:
|
||||
adr r0, per_dpll_param
|
||||
mov pc, lr
|
||||
284
cpu/arm_cortexa8/omap3/mem.c
Normal file
284
cpu/arm_cortexa8/omap3/mem.c
Normal file
@ -0,0 +1,284 @@
|
||||
/*
|
||||
* (C) Copyright 2008
|
||||
* Texas Instruments, <www.ti.com>
|
||||
*
|
||||
* Author :
|
||||
* Manikandan Pillai <mani.pillai@ti.com>
|
||||
*
|
||||
* Initial Code from:
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Syed Mohammed Khasim <khasim@ti.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/io.h>
|
||||
#include <asm/arch/mem.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <command.h>
|
||||
|
||||
/*
|
||||
* Only One NAND allowed on board at a time.
|
||||
* The GPMC CS Base for the same
|
||||
*/
|
||||
unsigned int boot_flash_base;
|
||||
unsigned int boot_flash_off;
|
||||
unsigned int boot_flash_sec;
|
||||
unsigned int boot_flash_type;
|
||||
volatile unsigned int boot_flash_env_addr;
|
||||
|
||||
#if defined(CONFIG_CMD_NAND)
|
||||
static u32 gpmc_m_nand[GPMC_MAX_REG] = {
|
||||
M_NAND_GPMC_CONFIG1,
|
||||
M_NAND_GPMC_CONFIG2,
|
||||
M_NAND_GPMC_CONFIG3,
|
||||
M_NAND_GPMC_CONFIG4,
|
||||
M_NAND_GPMC_CONFIG5,
|
||||
M_NAND_GPMC_CONFIG6, 0
|
||||
};
|
||||
|
||||
gpmc_csx_t *nand_cs_base;
|
||||
gpmc_t *gpmc_cfg_base;
|
||||
|
||||
#if defined(CONFIG_ENV_IS_IN_NAND)
|
||||
#define GPMC_CS 0
|
||||
#else
|
||||
#define GPMC_CS 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CMD_ONENAND)
|
||||
static u32 gpmc_onenand[GPMC_MAX_REG] = {
|
||||
ONENAND_GPMC_CONFIG1,
|
||||
ONENAND_GPMC_CONFIG2,
|
||||
ONENAND_GPMC_CONFIG3,
|
||||
ONENAND_GPMC_CONFIG4,
|
||||
ONENAND_GPMC_CONFIG5,
|
||||
ONENAND_GPMC_CONFIG6, 0
|
||||
};
|
||||
|
||||
gpmc_csx_t *onenand_cs_base;
|
||||
|
||||
#if defined(CONFIG_ENV_IS_IN_ONENAND)
|
||||
#define GPMC_CS 0
|
||||
#else
|
||||
#define GPMC_CS 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static sdrc_t *sdrc_base = (sdrc_t *)OMAP34XX_SDRC_BASE;
|
||||
|
||||
/**************************************************************************
|
||||
* make_cs1_contiguous() - for es2 and above remap cs1 behind cs0 to allow
|
||||
* command line mem=xyz use all memory with out discontinuous support
|
||||
* compiled in. Could do it at the ATAG, but there really is two banks...
|
||||
* Called as part of 2nd phase DDR init.
|
||||
**************************************************************************/
|
||||
void make_cs1_contiguous(void)
|
||||
{
|
||||
u32 size, a_add_low, a_add_high;
|
||||
|
||||
size = get_sdr_cs_size(CS0);
|
||||
size /= SZ_32M; /* find size to offset CS1 */
|
||||
a_add_high = (size & 3) << 8; /* set up low field */
|
||||
a_add_low = (size & 0x3C) >> 2; /* set up high field */
|
||||
writel((a_add_high | a_add_low), &sdrc_base->cs_cfg);
|
||||
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* mem_ok() - test used to see if timings are correct
|
||||
* for a part. Helps in guessing which part
|
||||
* we are currently using.
|
||||
*******************************************************/
|
||||
u32 mem_ok(u32 cs)
|
||||
{
|
||||
u32 val1, val2, addr;
|
||||
u32 pattern = 0x12345678;
|
||||
|
||||
addr = OMAP34XX_SDRC_CS0 + get_sdr_cs_offset(cs);
|
||||
|
||||
writel(0x0, addr + 0x400); /* clear pos A */
|
||||
writel(pattern, addr); /* pattern to pos B */
|
||||
writel(0x0, addr + 4); /* remove pattern off the bus */
|
||||
val1 = readl(addr + 0x400); /* get pos A value */
|
||||
val2 = readl(addr); /* get val2 */
|
||||
|
||||
if ((val1 != 0) || (val2 != pattern)) /* see if pos A val changed */
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* sdrc_init() - init the sdrc chip selects CS0 and CS1
|
||||
* - early init routines, called from flash or
|
||||
* SRAM.
|
||||
*******************************************************/
|
||||
void sdrc_init(void)
|
||||
{
|
||||
/* only init up first bank here */
|
||||
do_sdrc_init(CS0, EARLY_INIT);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* do_sdrc_init(): initialize the SDRAM for use.
|
||||
* -code sets up SDRAM basic SDRC timings for CS0
|
||||
* -optimal settings can be placed here, or redone after i2c
|
||||
* inspection of board info
|
||||
*
|
||||
* - code called once in C-Stack only context for CS0 and a possible 2nd
|
||||
* time depending on memory configuration from stack+global context
|
||||
**************************************************************************/
|
||||
|
||||
void do_sdrc_init(u32 cs, u32 early)
|
||||
{
|
||||
sdrc_actim_t *sdrc_actim_base;
|
||||
|
||||
if(cs)
|
||||
sdrc_actim_base = (sdrc_actim_t *)SDRC_ACTIM_CTRL1_BASE;
|
||||
else
|
||||
sdrc_actim_base = (sdrc_actim_t *)SDRC_ACTIM_CTRL0_BASE;
|
||||
|
||||
if (early) {
|
||||
/* reset sdrc controller */
|
||||
writel(SOFTRESET, &sdrc_base->sysconfig);
|
||||
wait_on_value(RESETDONE, RESETDONE, &sdrc_base->status,
|
||||
12000000);
|
||||
writel(0, &sdrc_base->sysconfig);
|
||||
|
||||
/* setup sdrc to ball mux */
|
||||
writel(SDP_SDRC_SHARING, &sdrc_base->sharing);
|
||||
|
||||
/* Disable Power Down of CKE cuz of 1 CKE on combo part */
|
||||
writel(SRFRONRESET | PAGEPOLICY_HIGH, &sdrc_base->power);
|
||||
|
||||
writel(ENADLL | DLLPHASE_90, &sdrc_base->dlla_ctrl);
|
||||
sdelay(0x20000);
|
||||
}
|
||||
|
||||
writel(RASWIDTH_13BITS | CASWIDTH_10BITS | ADDRMUXLEGACY |
|
||||
RAMSIZE_128 | BANKALLOCATION | B32NOT16 | B32NOT16 |
|
||||
DEEPPD | DDR_SDRAM, &sdrc_base->cs[cs].mcfg);
|
||||
writel(ARCV | ARE_ARCV_1, &sdrc_base->cs[cs].rfr_ctrl);
|
||||
writel(V_ACTIMA_165, &sdrc_actim_base->ctrla);
|
||||
writel(V_ACTIMB_165, &sdrc_actim_base->ctrlb);
|
||||
|
||||
writel(CMD_NOP, &sdrc_base ->cs[cs].manual);
|
||||
writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual);
|
||||
writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual);
|
||||
writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual);
|
||||
|
||||
/*
|
||||
* CAS latency 3, Write Burst = Read Burst, Serial Mode,
|
||||
* Burst length = 4
|
||||
*/
|
||||
writel(CASL3 | BURSTLENGTH4, &sdrc_base->cs[cs].mr);
|
||||
|
||||
if (!mem_ok(cs))
|
||||
writel(0, &sdrc_base->cs[cs].mcfg);
|
||||
}
|
||||
|
||||
void enable_gpmc_config(u32 *gpmc_config, gpmc_csx_t *gpmc_cs_base, u32 base,
|
||||
u32 size)
|
||||
{
|
||||
writel(0, &gpmc_cs_base->config7);
|
||||
sdelay(1000);
|
||||
/* Delay for settling */
|
||||
writel(gpmc_config[0], &gpmc_cs_base->config1);
|
||||
writel(gpmc_config[1], &gpmc_cs_base->config2);
|
||||
writel(gpmc_config[2], &gpmc_cs_base->config3);
|
||||
writel(gpmc_config[3], &gpmc_cs_base->config4);
|
||||
writel(gpmc_config[4], &gpmc_cs_base->config5);
|
||||
writel(gpmc_config[5], &gpmc_cs_base->config6);
|
||||
/* Enable the config */
|
||||
writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) |
|
||||
(1 << 6)), &gpmc_cs_base->config7);
|
||||
sdelay(2000);
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* gpmc_init(): init gpmc bus
|
||||
* Init GPMC for x16, MuxMode (SDRAM in x32).
|
||||
* This code can only be executed from SRAM or SDRAM.
|
||||
*****************************************************/
|
||||
void gpmc_init(void)
|
||||
{
|
||||
/* putting a blanket check on GPMC based on ZeBu for now */
|
||||
u32 *gpmc_config = NULL;
|
||||
gpmc_t *gpmc_base = (gpmc_t *)GPMC_BASE;
|
||||
gpmc_csx_t *gpmc_cs_base = (gpmc_csx_t *)GPMC_CONFIG_CS0_BASE;
|
||||
u32 base = 0;
|
||||
u32 size = 0;
|
||||
u32 f_off = CONFIG_SYS_MONITOR_LEN;
|
||||
u32 f_sec = 0;
|
||||
u32 config = 0;
|
||||
|
||||
/* global settings */
|
||||
writel(0, &gpmc_base->irqenable); /* isr's sources masked */
|
||||
writel(0, &gpmc_base->timeout_control);/* timeout disable */
|
||||
|
||||
config = readl(&gpmc_base->config);
|
||||
config &= (~0xf00);
|
||||
writel(config, &gpmc_base->config);
|
||||
|
||||
/*
|
||||
* Disable the GPMC0 config set by ROM code
|
||||
* It conflicts with our MPDB (both at 0x08000000)
|
||||
*/
|
||||
writel(0, &gpmc_cs_base->config7);
|
||||
sdelay(1000);
|
||||
|
||||
#if defined(CONFIG_CMD_NAND) /* CS 0 */
|
||||
gpmc_config = gpmc_m_nand;
|
||||
gpmc_cfg_base = gpmc_base;
|
||||
nand_cs_base = (gpmc_csx_t *)(GPMC_CONFIG_CS0_BASE +
|
||||
(GPMC_CS * GPMC_CONFIG_WIDTH));
|
||||
base = PISMO1_NAND_BASE;
|
||||
size = PISMO1_NAND_SIZE;
|
||||
enable_gpmc_config(gpmc_config, nand_cs_base, base, size);
|
||||
#if defined(CONFIG_ENV_IS_IN_NAND)
|
||||
f_off = SMNAND_ENV_OFFSET;
|
||||
f_sec = SZ_128K;
|
||||
/* env setup */
|
||||
boot_flash_base = base;
|
||||
boot_flash_off = f_off;
|
||||
boot_flash_sec = f_sec;
|
||||
boot_flash_env_addr = f_off;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CMD_ONENAND)
|
||||
gpmc_config = gpmc_onenand;
|
||||
onenand_cs_base = (gpmc_csx_t *)(GPMC_CONFIG_CS0_BASE +
|
||||
(GPMC_CS * GPMC_CONFIG_WIDTH));
|
||||
base = PISMO1_ONEN_BASE;
|
||||
size = PISMO1_ONEN_SIZE;
|
||||
enable_gpmc_config(gpmc_config, onenand_cs_base, base, size);
|
||||
#if defined(CONFIG_ENV_IS_IN_ONENAND)
|
||||
f_off = ONENAND_ENV_OFFSET;
|
||||
f_sec = SZ_128K;
|
||||
/* env setup */
|
||||
boot_flash_base = base;
|
||||
boot_flash_off = f_off;
|
||||
boot_flash_sec = f_sec;
|
||||
boot_flash_env_addr = f_off;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
254
cpu/arm_cortexa8/omap3/sys_info.c
Normal file
254
cpu/arm_cortexa8/omap3/sys_info.c
Normal file
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* (C) Copyright 2008
|
||||
* Texas Instruments, <www.ti.com>
|
||||
*
|
||||
* Author :
|
||||
* Manikandan Pillai <mani.pillai@ti.com>
|
||||
*
|
||||
* Derived from Beagle Board and 3430 SDP code by
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Syed Mohammed Khasim <khasim@ti.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/io.h>
|
||||
#include <asm/arch/mem.h> /* get mem tables */
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <i2c.h>
|
||||
|
||||
extern omap3_sysinfo sysinfo;
|
||||
static gpmc_csx_t *gpmc_cs_base = (gpmc_csx_t *)GPMC_CONFIG_CS0_BASE;
|
||||
static sdrc_t *sdrc_base = (sdrc_t *)OMAP34XX_SDRC_BASE;
|
||||
static ctrl_t *ctrl_base = (ctrl_t *)OMAP34XX_CTRL_BASE;
|
||||
|
||||
/******************************************
|
||||
* get_cpu_rev(void) - extract version info
|
||||
******************************************/
|
||||
u32 get_cpu_rev(void)
|
||||
{
|
||||
u32 cpuid = 0;
|
||||
|
||||
/*
|
||||
* On ES1.0 the IDCODE register is not exposed on L4
|
||||
* so using CPU ID to differentiate
|
||||
* between ES2.0 and ES1.0.
|
||||
*/
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r"(cpuid));
|
||||
if ((cpuid & 0xf) == 0x0)
|
||||
return CPU_3430_ES1;
|
||||
else
|
||||
return CPU_3430_ES2;
|
||||
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
* is_mem_sdr() - return 1 if mem type in use is SDR
|
||||
****************************************************/
|
||||
u32 is_mem_sdr(void)
|
||||
{
|
||||
if (readl(&sdrc_base->cs[CS0].mr) == SDP_SDRC_MR_0_SDR)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_cs0_size() - get size of chip select 0/1
|
||||
************************************************************************/
|
||||
u32 get_sdr_cs_size(u32 cs)
|
||||
{
|
||||
u32 size;
|
||||
|
||||
/* get ram size field */
|
||||
size = readl(&sdrc_base->cs[cs].mcfg) >> 8;
|
||||
size &= 0x3FF; /* remove unwanted bits */
|
||||
size *= SZ_2M; /* find size in MB */
|
||||
return size;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_sdr_cs_offset() - get offset of cs from cs0 start
|
||||
************************************************************************/
|
||||
u32 get_sdr_cs_offset(u32 cs)
|
||||
{
|
||||
u32 offset;
|
||||
|
||||
if (!cs)
|
||||
return 0;
|
||||
|
||||
offset = readl(&sdrc_base->cs_cfg);
|
||||
offset = (offset & 15) << 27 | (offset & 0x30) >> 17;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_board_type() - get board type based on current production stats.
|
||||
* - NOTE-1-: 2 I2C EEPROMs will someday be populated with proper info.
|
||||
* when they are available we can get info from there. This should
|
||||
* be correct of all known boards up until today.
|
||||
* - NOTE-2- EEPROMs are populated but they are updated very slowly. To
|
||||
* avoid waiting on them we will use ES version of the chip to get info.
|
||||
* A later version of the FPGA migth solve their speed issue.
|
||||
************************************************************************/
|
||||
u32 get_board_type(void)
|
||||
{
|
||||
if (get_cpu_rev() == CPU_3430_ES2)
|
||||
return sysinfo.board_type_v2;
|
||||
else
|
||||
return sysinfo.board_type_v1;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* get_gpmc0_base() - Return current address hardware will be
|
||||
* fetching from. The below effectively gives what is correct, its a bit
|
||||
* mis-leading compared to the TRM. For the most general case the mask
|
||||
* needs to be also taken into account this does work in practice.
|
||||
* - for u-boot we currently map:
|
||||
* -- 0 to nothing,
|
||||
* -- 4 to flash
|
||||
* -- 8 to enent
|
||||
* -- c to wifi
|
||||
****************************************************************************/
|
||||
u32 get_gpmc0_base(void)
|
||||
{
|
||||
u32 b;
|
||||
|
||||
b = readl(&gpmc_cs_base->config7);
|
||||
b &= 0x1F; /* keep base [5:0] */
|
||||
b = b << 24; /* ret 0x0b000000 */
|
||||
return b;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* get_gpmc0_width() - See if bus is in x8 or x16 (mainly for nand)
|
||||
*******************************************************************/
|
||||
u32 get_gpmc0_width(void)
|
||||
{
|
||||
return WIDTH_16BIT;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* get_board_rev() - setup to pass kernel board revision information
|
||||
* returns:(bit[0-3] sub version, higher bit[7-4] is higher version)
|
||||
*************************************************************************/
|
||||
u32 get_board_rev(void)
|
||||
{
|
||||
return 0x20;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* display_board_info() - print banner with board info.
|
||||
*********************************************************************/
|
||||
void display_board_info(u32 btype)
|
||||
{
|
||||
char *mem_s, *sec_s;
|
||||
|
||||
if (is_mem_sdr())
|
||||
mem_s = "mSDR";
|
||||
else
|
||||
mem_s = "LPDDR";
|
||||
|
||||
switch (get_device_type()) {
|
||||
case TST_DEVICE:
|
||||
sec_s = "TST";
|
||||
break;
|
||||
case EMU_DEVICE:
|
||||
sec_s = "EMU";
|
||||
break;
|
||||
case HS_DEVICE:
|
||||
sec_s = "HS";
|
||||
break;
|
||||
case GP_DEVICE:
|
||||
sec_s = "GP";
|
||||
break;
|
||||
default:
|
||||
sec_s = "?";
|
||||
}
|
||||
|
||||
printf("OMAP%s-%s rev %d, CPU-OPP2 L3-165MHz\n", sysinfo.cpu_string,
|
||||
sec_s, get_cpu_rev());
|
||||
printf("%s + %s/%s\n", sysinfo.board_string,
|
||||
mem_s, sysinfo.nand_string);
|
||||
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* get_base(); get upper addr of current execution
|
||||
*******************************************************/
|
||||
u32 get_base(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
__asm__ __volatile__("mov %0, pc \n":"=r"(val)::"memory");
|
||||
val &= 0xF0000000;
|
||||
val >>= 28;
|
||||
return val;
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* is_running_in_flash() - tell if currently running in
|
||||
* FLASH.
|
||||
*******************************************************/
|
||||
u32 is_running_in_flash(void)
|
||||
{
|
||||
if (get_base() < 4)
|
||||
return 1; /* in FLASH */
|
||||
|
||||
return 0; /* running in SRAM or SDRAM */
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* is_running_in_sram() - tell if currently running in
|
||||
* SRAM.
|
||||
*******************************************************/
|
||||
u32 is_running_in_sram(void)
|
||||
{
|
||||
if (get_base() == 4)
|
||||
return 1; /* in SRAM */
|
||||
|
||||
return 0; /* running in FLASH or SDRAM */
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* is_running_in_sdram() - tell if currently running in
|
||||
* SDRAM.
|
||||
*******************************************************/
|
||||
u32 is_running_in_sdram(void)
|
||||
{
|
||||
if (get_base() > 4)
|
||||
return 1; /* in SDRAM */
|
||||
|
||||
return 0; /* running in SRAM or FLASH */
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* get_boot_type() - Is this an XIP type device or a stream one
|
||||
* bits 4-0 specify type. Bit 5 says mem/perif
|
||||
***************************************************************/
|
||||
u32 get_boot_type(void)
|
||||
{
|
||||
return (readl(&ctrl_base->status) & SYSBOOT_MASK);
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* get_device_type(): tell if GP/HS/EMU/TST
|
||||
*************************************************************/
|
||||
u32 get_device_type(void)
|
||||
{
|
||||
return ((readl(&ctrl_base->status) & (DEVICE_MASK)) >> 8);
|
||||
}
|
||||
72
cpu/arm_cortexa8/omap3/syslib.c
Normal file
72
cpu/arm_cortexa8/omap3/syslib.c
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* (C) Copyright 2008
|
||||
* Texas Instruments, <www.ti.com>
|
||||
*
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Syed Mohammed Khasim <khasim@ti.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/io.h>
|
||||
#include <asm/arch/mem.h>
|
||||
#include <asm/arch/clocks.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
|
||||
/************************************************************
|
||||
* sdelay() - simple spin loop. Will be constant time as
|
||||
* its generally used in bypass conditions only. This
|
||||
* is necessary until timers are accessible.
|
||||
*
|
||||
* not inline to increase chances its in cache when called
|
||||
*************************************************************/
|
||||
void sdelay(unsigned long loops)
|
||||
{
|
||||
__asm__ volatile ("1:\n" "subs %0, %1, #1\n"
|
||||
"bne 1b":"=r" (loops):"0"(loops));
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* sr32 - clear & set a value in a bit range for a 32 bit address
|
||||
*****************************************************************/
|
||||
void sr32(void *addr, u32 start_bit, u32 num_bits, u32 value)
|
||||
{
|
||||
u32 tmp, msk = 0;
|
||||
msk = 1 << num_bits;
|
||||
--msk;
|
||||
tmp = readl((u32)addr) & ~(msk << start_bit);
|
||||
tmp |= value << start_bit;
|
||||
writel(tmp, (u32)addr);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* wait_on_value() - common routine to allow waiting for changes in
|
||||
* volatile regs.
|
||||
*********************************************************************/
|
||||
u32 wait_on_value(u32 read_bit_mask, u32 match_value, void *read_addr,
|
||||
u32 bound)
|
||||
{
|
||||
u32 i = 0, val;
|
||||
do {
|
||||
++i;
|
||||
val = readl((u32)read_addr) & read_bit_mask;
|
||||
if (val == match_value)
|
||||
return 1;
|
||||
if (i == bound)
|
||||
return 0;
|
||||
} while (1);
|
||||
}
|
||||
518
cpu/arm_cortexa8/start.S
Normal file
518
cpu/arm_cortexa8/start.S
Normal file
@ -0,0 +1,518 @@
|
||||
/*
|
||||
* armboot - Startup Code for OMAP3530/ARM Cortex CPU-core
|
||||
*
|
||||
* Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
|
||||
*
|
||||
* Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
|
||||
* Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
|
||||
* Copyright (c) 2002 Gary Jennejohn <gj@denx.de>
|
||||
* Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Copyright (c) 2003 Kshitij <kshitij@ti.com>
|
||||
* Copyright (c) 2006-2008 Syed Mohammed Khasim <x0khasim@ti.com>
|
||||
* Copyright (c) 2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include <version.h>
|
||||
|
||||
.globl _start
|
||||
_start: b reset
|
||||
ldr pc, _undefined_instruction
|
||||
ldr pc, _software_interrupt
|
||||
ldr pc, _prefetch_abort
|
||||
ldr pc, _data_abort
|
||||
ldr pc, _not_used
|
||||
ldr pc, _irq
|
||||
ldr pc, _fiq
|
||||
|
||||
_undefined_instruction: .word undefined_instruction
|
||||
_software_interrupt: .word software_interrupt
|
||||
_prefetch_abort: .word prefetch_abort
|
||||
_data_abort: .word data_abort
|
||||
_not_used: .word not_used
|
||||
_irq: .word irq
|
||||
_fiq: .word fiq
|
||||
_pad: .word 0x12345678 /* now 16*4=64 */
|
||||
.global _end_vect
|
||||
_end_vect:
|
||||
|
||||
.balignl 16,0xdeadbeef
|
||||
/*************************************************************************
|
||||
*
|
||||
* Startup Code (reset vector)
|
||||
*
|
||||
* do important init only if we don't start from memory!
|
||||
* setup Memory and board specific bits prior to relocation.
|
||||
* relocate armboot to ram
|
||||
* setup stack
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
_TEXT_BASE:
|
||||
.word TEXT_BASE
|
||||
|
||||
.globl _armboot_start
|
||||
_armboot_start:
|
||||
.word _start
|
||||
|
||||
/*
|
||||
* These are defined in the board-specific linker script.
|
||||
*/
|
||||
.globl _bss_start
|
||||
_bss_start:
|
||||
.word __bss_start
|
||||
|
||||
.globl _bss_end
|
||||
_bss_end:
|
||||
.word _end
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
/* IRQ stack memory (calculated at run-time) */
|
||||
.globl IRQ_STACK_START
|
||||
IRQ_STACK_START:
|
||||
.word 0x0badc0de
|
||||
|
||||
/* IRQ stack memory (calculated at run-time) */
|
||||
.globl FIQ_STACK_START
|
||||
FIQ_STACK_START:
|
||||
.word 0x0badc0de
|
||||
#endif
|
||||
|
||||
/*
|
||||
* the actual reset code
|
||||
*/
|
||||
|
||||
reset:
|
||||
/*
|
||||
* set the cpu to SVC32 mode
|
||||
*/
|
||||
mrs r0, cpsr
|
||||
bic r0, r0, #0x1f
|
||||
orr r0, r0, #0xd3
|
||||
msr cpsr,r0
|
||||
|
||||
#if (CONFIG_OMAP34XX)
|
||||
/* Copy vectors to mask ROM indirect addr */
|
||||
adr r0, _start @ r0 <- current position of code
|
||||
add r0, r0, #4 @ skip reset vector
|
||||
mov r2, #64 @ r2 <- size to copy
|
||||
add r2, r0, r2 @ r2 <- source end address
|
||||
mov r1, #SRAM_OFFSET0 @ build vect addr
|
||||
mov r3, #SRAM_OFFSET1
|
||||
add r1, r1, r3
|
||||
mov r3, #SRAM_OFFSET2
|
||||
add r1, r1, r3
|
||||
next:
|
||||
ldmia r0!, {r3 - r10} @ copy from source address [r0]
|
||||
stmia r1!, {r3 - r10} @ copy to target address [r1]
|
||||
cmp r0, r2 @ until source end address [r2]
|
||||
bne next @ loop until equal */
|
||||
#if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_ONENAND_BOOT)
|
||||
/* No need to copy/exec the clock code - DPLL adjust already done
|
||||
* in NAND/oneNAND Boot.
|
||||
*/
|
||||
bl cpy_clk_code @ put dpll adjust code behind vectors
|
||||
#endif /* NAND Boot */
|
||||
#endif
|
||||
/* the mask ROM code should have PLL and others stable */
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
bl cpu_init_crit
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
|
||||
relocate: @ relocate U-Boot to RAM
|
||||
adr r0, _start @ r0 <- current position of code
|
||||
ldr r1, _TEXT_BASE @ test if we run from flash or RAM
|
||||
cmp r0, r1 @ don't reloc during debug
|
||||
beq stack_setup
|
||||
|
||||
ldr r2, _armboot_start
|
||||
ldr r3, _bss_start
|
||||
sub r2, r3, r2 @ r2 <- size of armboot
|
||||
add r2, r0, r2 @ r2 <- source end address
|
||||
|
||||
copy_loop: @ copy 32 bytes at a time
|
||||
ldmia r0!, {r3 - r10} @ copy from source address [r0]
|
||||
stmia r1!, {r3 - r10} @ copy to target address [r1]
|
||||
cmp r0, r2 @ until source end addreee [r2]
|
||||
ble copy_loop
|
||||
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
|
||||
|
||||
/* Set up the stack */
|
||||
stack_setup:
|
||||
ldr r0, _TEXT_BASE @ upper 128 KiB: relocated uboot
|
||||
sub r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area
|
||||
sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
sub r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ)
|
||||
#endif
|
||||
sub sp, r0, #12 @ leave 3 words for abort-stack
|
||||
and sp, sp, #~7 @ 8 byte alinged for (ldr/str)d
|
||||
|
||||
/* Clear BSS (if any). Is below tx (watch load addr - need space) */
|
||||
clear_bss:
|
||||
ldr r0, _bss_start @ find start of bss segment
|
||||
ldr r1, _bss_end @ stop here
|
||||
mov r2, #0x00000000 @ clear value
|
||||
clbss_l:
|
||||
str r2, [r0] @ clear BSS location
|
||||
cmp r0, r1 @ are we at the end yet
|
||||
add r0, r0, #4 @ increment clear index pointer
|
||||
bne clbss_l @ keep clearing till at end
|
||||
|
||||
ldr pc, _start_armboot @ jump to C code
|
||||
|
||||
_start_armboot: .word start_armboot
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* CPU_init_critical registers
|
||||
*
|
||||
* setup important registers
|
||||
* setup memory timing
|
||||
*
|
||||
*************************************************************************/
|
||||
cpu_init_crit:
|
||||
/*
|
||||
* Invalidate L1 I/D
|
||||
*/
|
||||
mov r0, #0 @ set up for MCR
|
||||
mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
|
||||
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
|
||||
|
||||
/*
|
||||
* disable MMU stuff and caches
|
||||
*/
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
|
||||
bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
|
||||
orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
|
||||
orr r0, r0, #0x00000800 @ set bit 12 (Z---) BTB
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
/*
|
||||
* Jump to board specific initialization...
|
||||
* The Mask ROM will have already initialized
|
||||
* basic memory. Go here to bump up clock rate and handle
|
||||
* wake up conditions.
|
||||
*/
|
||||
mov ip, lr @ persevere link reg across call
|
||||
bl lowlevel_init @ go setup pll,mux,memory
|
||||
mov lr, ip @ restore link
|
||||
mov pc, lr @ back to my caller
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* Interrupt handling
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
@
|
||||
@ IRQ stack frame.
|
||||
@
|
||||
#define S_FRAME_SIZE 72
|
||||
|
||||
#define S_OLD_R0 68
|
||||
#define S_PSR 64
|
||||
#define S_PC 60
|
||||
#define S_LR 56
|
||||
#define S_SP 52
|
||||
|
||||
#define S_IP 48
|
||||
#define S_FP 44
|
||||
#define S_R10 40
|
||||
#define S_R9 36
|
||||
#define S_R8 32
|
||||
#define S_R7 28
|
||||
#define S_R6 24
|
||||
#define S_R5 20
|
||||
#define S_R4 16
|
||||
#define S_R3 12
|
||||
#define S_R2 8
|
||||
#define S_R1 4
|
||||
#define S_R0 0
|
||||
|
||||
#define MODE_SVC 0x13
|
||||
#define I_BIT 0x80
|
||||
|
||||
/*
|
||||
* use bad_save_user_regs for abort/prefetch/undef/swi ...
|
||||
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
|
||||
*/
|
||||
|
||||
.macro bad_save_user_regs
|
||||
sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current
|
||||
@ user stack
|
||||
stmia sp, {r0 - r12} @ Save user registers (now in
|
||||
@ svc mode) r0-r12
|
||||
|
||||
ldr r2, _armboot_start
|
||||
sub r2, r2, #(CONFIG_SYS_MALLOC_LEN)
|
||||
sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE + 8) @ set base 2 words into abort
|
||||
@ stack
|
||||
ldmia r2, {r2 - r3} @ get values for "aborted" pc
|
||||
@ and cpsr (into parm regs)
|
||||
add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
|
||||
|
||||
add r5, sp, #S_SP
|
||||
mov r1, lr
|
||||
stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
|
||||
mov r0, sp @ save current stack into r0
|
||||
@ (param register)
|
||||
.endm
|
||||
|
||||
.macro irq_save_user_regs
|
||||
sub sp, sp, #S_FRAME_SIZE
|
||||
stmia sp, {r0 - r12} @ Calling r0-r12
|
||||
add r8, sp, #S_PC @ !! R8 NEEDS to be saved !!
|
||||
@ a reserved stack spot would
|
||||
@ be good.
|
||||
stmdb r8, {sp, lr}^ @ Calling SP, LR
|
||||
str lr, [r8, #0] @ Save calling PC
|
||||
mrs r6, spsr
|
||||
str r6, [r8, #4] @ Save CPSR
|
||||
str r0, [r8, #8] @ Save OLD_R0
|
||||
mov r0, sp
|
||||
.endm
|
||||
|
||||
.macro irq_restore_user_regs
|
||||
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
|
||||
mov r0, r0
|
||||
ldr lr, [sp, #S_PC] @ Get PC
|
||||
add sp, sp, #S_FRAME_SIZE
|
||||
subs pc, lr, #4 @ return & move spsr_svc into
|
||||
@ cpsr
|
||||
.endm
|
||||
|
||||
.macro get_bad_stack
|
||||
ldr r13, _armboot_start @ setup our mode stack (enter
|
||||
@ in banked mode)
|
||||
sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool
|
||||
sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8) @ move to reserved a couple
|
||||
@ spots for abort stack
|
||||
|
||||
str lr, [r13] @ save caller lr in position 0
|
||||
@ of saved stack
|
||||
mrs lr, spsr @ get the spsr
|
||||
str lr, [r13, #4] @ save spsr in position 1 of
|
||||
@ saved stack
|
||||
|
||||
mov r13, #MODE_SVC @ prepare SVC-Mode
|
||||
@ msr spsr_c, r13
|
||||
msr spsr, r13 @ switch modes, make sure
|
||||
@ moves will execute
|
||||
mov lr, pc @ capture return pc
|
||||
movs pc, lr @ jump to next instruction &
|
||||
@ switch modes.
|
||||
.endm
|
||||
|
||||
.macro get_bad_stack_swi
|
||||
sub r13, r13, #4 @ space on current stack for
|
||||
@ scratch reg.
|
||||
str r0, [r13] @ save R0's value.
|
||||
ldr r0, _armboot_start @ get data regions start
|
||||
sub r0, r0, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool
|
||||
sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8) @ move past gbl and a couple
|
||||
@ spots for abort stack
|
||||
str lr, [r0] @ save caller lr in position 0
|
||||
@ of saved stack
|
||||
mrs r0, spsr @ get the spsr
|
||||
str lr, [r0, #4] @ save spsr in position 1 of
|
||||
@ saved stack
|
||||
ldr r0, [r13] @ restore r0
|
||||
add r13, r13, #4 @ pop stack entry
|
||||
.endm
|
||||
|
||||
.macro get_irq_stack @ setup IRQ stack
|
||||
ldr sp, IRQ_STACK_START
|
||||
.endm
|
||||
|
||||
.macro get_fiq_stack @ setup FIQ stack
|
||||
ldr sp, FIQ_STACK_START
|
||||
.endm
|
||||
|
||||
/*
|
||||
* exception handlers
|
||||
*/
|
||||
.align 5
|
||||
undefined_instruction:
|
||||
get_bad_stack
|
||||
bad_save_user_regs
|
||||
bl do_undefined_instruction
|
||||
|
||||
.align 5
|
||||
software_interrupt:
|
||||
get_bad_stack_swi
|
||||
bad_save_user_regs
|
||||
bl do_software_interrupt
|
||||
|
||||
.align 5
|
||||
prefetch_abort:
|
||||
get_bad_stack
|
||||
bad_save_user_regs
|
||||
bl do_prefetch_abort
|
||||
|
||||
.align 5
|
||||
data_abort:
|
||||
get_bad_stack
|
||||
bad_save_user_regs
|
||||
bl do_data_abort
|
||||
|
||||
.align 5
|
||||
not_used:
|
||||
get_bad_stack
|
||||
bad_save_user_regs
|
||||
bl do_not_used
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
|
||||
.align 5
|
||||
irq:
|
||||
get_irq_stack
|
||||
irq_save_user_regs
|
||||
bl do_irq
|
||||
irq_restore_user_regs
|
||||
|
||||
.align 5
|
||||
fiq:
|
||||
get_fiq_stack
|
||||
/* someone ought to write a more effective fiq_save_user_regs */
|
||||
irq_save_user_regs
|
||||
bl do_fiq
|
||||
irq_restore_user_regs
|
||||
|
||||
#else
|
||||
|
||||
.align 5
|
||||
irq:
|
||||
get_bad_stack
|
||||
bad_save_user_regs
|
||||
bl do_irq
|
||||
|
||||
.align 5
|
||||
fiq:
|
||||
get_bad_stack
|
||||
bad_save_user_regs
|
||||
bl do_fiq
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* v7_flush_dcache_all()
|
||||
*
|
||||
* Flush the whole D-cache.
|
||||
*
|
||||
* Corrupted registers: r0-r5, r7, r9-r11
|
||||
*
|
||||
* - mm - mm_struct describing address space
|
||||
*/
|
||||
.align 5
|
||||
.global v7_flush_dcache_all
|
||||
v7_flush_dcache_all:
|
||||
stmfd r13!, {r0 - r5, r7, r9 - r12, r14}
|
||||
|
||||
mov r7, r0 @ take a backup of device type
|
||||
cmp r0, #0x3 @ check if the device type is
|
||||
@ GP
|
||||
moveq r12, #0x1 @ set up to invalide L2
|
||||
smi: .word 0x01600070 @ Call SMI monitor (smieq)
|
||||
cmp r7, #0x3 @ compare again in case its
|
||||
@ lost
|
||||
beq finished_inval @ if GP device, inval done
|
||||
@ above
|
||||
|
||||
mrc p15, 1, r0, c0, c0, 1 @ read clidr
|
||||
ands r3, r0, #0x7000000 @ extract loc from clidr
|
||||
mov r3, r3, lsr #23 @ left align loc bit field
|
||||
beq finished_inval @ if loc is 0, then no need to
|
||||
@ clean
|
||||
mov r10, #0 @ start clean at cache level 0
|
||||
inval_loop1:
|
||||
add r2, r10, r10, lsr #1 @ work out 3x current cache
|
||||
@ level
|
||||
mov r1, r0, lsr r2 @ extract cache type bits from
|
||||
@ clidr
|
||||
and r1, r1, #7 @ mask of the bits for current
|
||||
@ cache only
|
||||
cmp r1, #2 @ see what cache we have at
|
||||
@ this level
|
||||
blt skip_inval @ skip if no cache, or just
|
||||
@ i-cache
|
||||
mcr p15, 2, r10, c0, c0, 0 @ select current cache level
|
||||
@ in cssr
|
||||
mov r2, #0 @ operand for mcr SBZ
|
||||
mcr p15, 0, r2, c7, c5, 4 @ flush prefetch buffer to
|
||||
@ sych the new cssr&csidr,
|
||||
@ with armv7 this is 'isb',
|
||||
@ but we compile with armv5
|
||||
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
|
||||
and r2, r1, #7 @ extract the length of the
|
||||
@ cache lines
|
||||
add r2, r2, #4 @ add 4 (line length offset)
|
||||
ldr r4, =0x3ff
|
||||
ands r4, r4, r1, lsr #3 @ find maximum number on the
|
||||
@ way size
|
||||
clz r5, r4 @ find bit position of way
|
||||
@ size increment
|
||||
ldr r7, =0x7fff
|
||||
ands r7, r7, r1, lsr #13 @ extract max number of the
|
||||
@ index size
|
||||
inval_loop2:
|
||||
mov r9, r4 @ create working copy of max
|
||||
@ way size
|
||||
inval_loop3:
|
||||
orr r11, r10, r9, lsl r5 @ factor way and cache number
|
||||
@ into r11
|
||||
orr r11, r11, r7, lsl r2 @ factor index number into r11
|
||||
mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
|
||||
subs r9, r9, #1 @ decrement the way
|
||||
bge inval_loop3
|
||||
subs r7, r7, #1 @ decrement the index
|
||||
bge inval_loop2
|
||||
skip_inval:
|
||||
add r10, r10, #2 @ increment cache number
|
||||
cmp r3, r10
|
||||
bgt inval_loop1
|
||||
finished_inval:
|
||||
mov r10, #0 @ swith back to cache level 0
|
||||
mcr p15, 2, r10, c0, c0, 0 @ select current cache level
|
||||
@ in cssr
|
||||
mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer,
|
||||
@ with armv7 this is 'isb',
|
||||
@ but we compile with armv5
|
||||
|
||||
ldmfd r13!, {r0 - r5, r7, r9 - r12, pc}
|
||||
|
||||
#ifdef PRM_RSTCTRL
|
||||
.align 5
|
||||
.global reset_cpu
|
||||
reset_cpu:
|
||||
ldr r1, rstctl @ get addr for global reset
|
||||
@ reg
|
||||
mov r3, #0x2 @ full reset pll + mpu
|
||||
str r3, [r1] @ force reset
|
||||
mov r0, r0
|
||||
_loop_forever:
|
||||
b _loop_forever
|
||||
rstctl:
|
||||
.word PRM_RSTCTRL
|
||||
#endif
|
||||
@ -3,6 +3,8 @@
|
||||
*
|
||||
* (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
|
||||
*
|
||||
* (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
@ -26,8 +28,19 @@
|
||||
|
||||
#if defined(CONFIG_HARD_I2C)
|
||||
|
||||
#ifdef CONFIG_MX25
|
||||
#include <asm/arch/mx25.h>
|
||||
#include <asm/arch/mx25-regs.h>
|
||||
#elif defined(CONFIG_MX31)
|
||||
#include <asm/arch/mx31.h>
|
||||
#include <asm/arch/mx31-regs.h>
|
||||
#elif defined(CONFIG_MX35)
|
||||
#include <asm/arch/mx35.h>
|
||||
#elif defined(CONFIG_MX51_3DS)
|
||||
#include <asm/arch/mx51.h>
|
||||
#else
|
||||
#error "Please include specific headfile "
|
||||
#endif
|
||||
|
||||
#define IADR 0x00
|
||||
#define IFDR 0x04
|
||||
@ -47,16 +60,17 @@
|
||||
#define I2SR_IIF (1 << 1)
|
||||
#define I2SR_RX_NO_AK (1 << 0)
|
||||
|
||||
#ifdef CONFIG_SYS_I2C_MX31_PORT1
|
||||
#define I2C_BASE 0x43f80000
|
||||
#elif defined (CONFIG_SYS_I2C_MX31_PORT2)
|
||||
#define I2C_BASE 0x43f98000
|
||||
#elif defined (CONFIG_SYS_I2C_MX31_PORT3)
|
||||
#define I2C_BASE 0x43f84000
|
||||
#ifdef CONFIG_SYS_I2C_PORT
|
||||
# define I2C_BASE CONFIG_SYS_I2C_PORT
|
||||
#else
|
||||
#error "define CONFIG_SYS_I2C_MX31_PORTx to use the mx31 I2C driver"
|
||||
# error "define CONFIG_SYS_I2C_PORT(I2C base address) to use the I2C driver"
|
||||
#endif
|
||||
|
||||
#define I2C_MAX_TIMEOUT 100000
|
||||
#define I2C_TIMEOUT_TICKET 1
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DPRINTF(args...) printf(args)
|
||||
#else
|
||||
@ -64,33 +78,77 @@
|
||||
#endif
|
||||
|
||||
static u16 div[] = { 30, 32, 36, 42, 48, 52, 60, 72, 80, 88, 104, 128, 144,
|
||||
160, 192, 240, 288, 320, 384, 480, 576, 640, 768, 960,
|
||||
1152, 1280, 1536, 1920, 2304, 2560, 3072, 3840};
|
||||
160, 192, 240, 288, 320, 384, 480, 576, 640, 768, 960,
|
||||
1152, 1280, 1536, 1920, 2304, 2560, 3072, 3840
|
||||
};
|
||||
|
||||
static inline void i2c_reset(void)
|
||||
{
|
||||
__REG16(I2C_BASE + I2CR) = 0; /* Reset module */
|
||||
__REG16(I2C_BASE + I2SR) = 0;
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN;
|
||||
}
|
||||
|
||||
void i2c_init(int speed, int unused)
|
||||
{
|
||||
int freq = mx31_get_ipg_clk();
|
||||
int freq;
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_MX31
|
||||
freq = mx31_get_ipg_clk();
|
||||
#else
|
||||
freq = mxc_get_clock(MXC_IPG_PERCLK);
|
||||
#endif
|
||||
for (i = 0; i < 0x1f; i++)
|
||||
if (freq / div[i] <= speed)
|
||||
break;
|
||||
|
||||
DPRINTF("%s: speed: %d\n",__FUNCTION__, speed);
|
||||
DPRINTF("%s: root clock: %d, speed: %d div: %x\n",
|
||||
__func__, freq, speed, i);
|
||||
|
||||
__REG16(I2C_BASE + I2CR) = 0; /* Reset module */
|
||||
__REG16(I2C_BASE + IFDR) = i;
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN;
|
||||
__REG16(I2C_BASE + I2SR) = 0;
|
||||
i2c_reset();
|
||||
}
|
||||
|
||||
static int wait_idle(void)
|
||||
{
|
||||
int timeout = I2C_MAX_TIMEOUT;
|
||||
|
||||
while ((__REG16(I2C_BASE + I2SR) & I2SR_IBB) && --timeout) {
|
||||
__REG16(I2C_BASE + I2SR) = 0;
|
||||
udelay(I2C_TIMEOUT_TICKET);
|
||||
}
|
||||
DPRINTF("%s:%x\n", __func__, __REG16(I2C_BASE + I2SR));
|
||||
return timeout ? timeout : (!(__REG16(I2C_BASE + I2SR) & I2SR_IBB));
|
||||
}
|
||||
|
||||
static int wait_busy(void)
|
||||
{
|
||||
int timeout = 10000;
|
||||
int timeout = I2C_MAX_TIMEOUT;
|
||||
|
||||
while (!(__REG16(I2C_BASE + I2SR) & I2SR_IIF) && --timeout)
|
||||
udelay(1);
|
||||
__REG16(I2C_BASE + I2SR) = 0; /* clear interrupt */
|
||||
while ((!(__REG16(I2C_BASE + I2SR) & I2SR_IBB) && (--timeout))) {
|
||||
__REG16(I2C_BASE + I2SR) = 0;
|
||||
udelay(I2C_TIMEOUT_TICKET);
|
||||
}
|
||||
return timeout ? timeout : (__REG16(I2C_BASE + I2SR) & I2SR_IBB);
|
||||
}
|
||||
|
||||
static int wait_complete(void)
|
||||
{
|
||||
int timeout = I2C_MAX_TIMEOUT;
|
||||
|
||||
while ((!(__REG16(I2C_BASE + I2SR) & I2SR_ICF)) && (--timeout)) {
|
||||
__REG16(I2C_BASE + I2SR) = 0;
|
||||
udelay(I2C_TIMEOUT_TICKET);
|
||||
}
|
||||
DPRINTF("%s:%x\n", __func__, __REG16(I2C_BASE + I2SR));
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 200; i++)
|
||||
udelay(10);
|
||||
|
||||
}
|
||||
__REG16(I2C_BASE + I2SR) = 0; /* clear interrupt */
|
||||
|
||||
return timeout;
|
||||
}
|
||||
@ -99,90 +157,133 @@ static int tx_byte(u8 byte)
|
||||
{
|
||||
__REG16(I2C_BASE + I2DR) = byte;
|
||||
|
||||
if (!wait_busy() || __REG16(I2C_BASE + I2SR) & I2SR_RX_NO_AK)
|
||||
if (!wait_complete() || __REG16(I2C_BASE + I2SR) & I2SR_RX_NO_AK) {
|
||||
DPRINTF("%s:%x <= %x\n", __func__, __REG16(I2C_BASE + I2SR),
|
||||
byte);
|
||||
return -1;
|
||||
}
|
||||
DPRINTF("%s:%x\n", __func__, byte);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rx_byte(void)
|
||||
static int rx_byte(u32 *pdata, int last)
|
||||
{
|
||||
if (!wait_busy())
|
||||
if (!wait_complete())
|
||||
return -1;
|
||||
|
||||
return __REG16(I2C_BASE + I2DR);
|
||||
if (last)
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN;
|
||||
|
||||
*pdata = __REG16(I2C_BASE + I2DR);
|
||||
DPRINTF("%s:%x\n", __func__, *pdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_probe(uchar chip)
|
||||
{
|
||||
int ret;
|
||||
|
||||
__REG16(I2C_BASE + I2CR) = 0; /* Reset module */
|
||||
__REG16(I2C_BASE + I2CR) = 0; /* Reset module */
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN;
|
||||
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MSTA | I2CR_MTX;
|
||||
for (ret = 0; ret < 1000; ret++)
|
||||
udelay(1);
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MSTA | I2CR_MTX;
|
||||
ret = tx_byte(chip << 1);
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MTX;
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int i2c_addr(uchar chip, uint addr, int alen)
|
||||
{
|
||||
__REG16(I2C_BASE + I2SR) = 0; /* clear interrupt */
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MSTA | I2CR_MTX;
|
||||
|
||||
if (tx_byte(chip << 1))
|
||||
int i, retry = 0;
|
||||
for (retry = 0; retry < 3; retry++) {
|
||||
if (wait_idle())
|
||||
break;
|
||||
i2c_reset();
|
||||
for (i = 0; i < I2C_MAX_TIMEOUT; i++)
|
||||
udelay(I2C_TIMEOUT_TICKET);
|
||||
}
|
||||
if (retry >= 3) {
|
||||
printf("%s:bus is busy(%x)\n",
|
||||
__func__, __REG16(I2C_BASE + I2SR));
|
||||
return -1;
|
||||
|
||||
}
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MSTA | I2CR_MTX;
|
||||
if (!wait_busy()) {
|
||||
printf("%s:trigger start fail(%x)\n",
|
||||
__func__, __REG16(I2C_BASE + I2SR));
|
||||
return -1;
|
||||
}
|
||||
if (tx_byte(chip << 1) || (__REG16(I2C_BASE + I2SR) & I2SR_RX_NO_AK)) {
|
||||
printf("%s:chip address cycle fail(%x)\n",
|
||||
__func__, __REG16(I2C_BASE + I2SR));
|
||||
return -1;
|
||||
}
|
||||
while (alen--)
|
||||
if (tx_byte((addr >> (alen * 8)) & 0xff))
|
||||
if (tx_byte((addr >> (alen * 8)) & 0xff) ||
|
||||
(__REG16(I2C_BASE + I2SR) & I2SR_RX_NO_AK)) {
|
||||
printf("%s:device address cycle fail(%x)\n",
|
||||
__func__, __REG16(I2C_BASE + I2SR));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
|
||||
{
|
||||
int timeout = 10000;
|
||||
int timeout = I2C_MAX_TIMEOUT;
|
||||
int ret;
|
||||
|
||||
DPRINTF("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n",__FUNCTION__, chip, addr, alen, len);
|
||||
DPRINTF("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n",
|
||||
__func__, chip, addr, alen, len);
|
||||
|
||||
if (i2c_addr(chip, addr, alen)) {
|
||||
printf("i2c_addr failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MSTA | I2CR_MTX | I2CR_RSTA;
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MSTA | I2CR_MTX | I2CR_RSTA;
|
||||
|
||||
if (tx_byte(chip << 1 | 1))
|
||||
if (tx_byte(chip << 1 | 1) ||
|
||||
(__REG16(I2C_BASE + I2SR) & I2SR_RX_NO_AK)) {
|
||||
printf("%s:Send 2th chip address fail(%x)\n",
|
||||
__func__, __REG16(I2C_BASE + I2SR));
|
||||
return -1;
|
||||
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MSTA | ((len == 1) ? I2CR_TX_NO_AK : 0);
|
||||
|
||||
}
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MSTA |
|
||||
((len == 1) ? I2CR_TX_NO_AK : 0);
|
||||
DPRINTF("CR=%x\n", __REG16(I2C_BASE + I2CR));
|
||||
ret = __REG16(I2C_BASE + I2DR);
|
||||
|
||||
while (len--) {
|
||||
if ((ret = rx_byte()) < 0)
|
||||
if (len == 1)
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MSTA |
|
||||
I2CR_TX_NO_AK;
|
||||
|
||||
if (rx_byte(&ret, len == 0) < 0) {
|
||||
printf("Read: rx_byte fail\n");
|
||||
return -1;
|
||||
}
|
||||
*buf++ = ret;
|
||||
if (len <= 1)
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MSTA | I2CR_TX_NO_AK;
|
||||
}
|
||||
|
||||
wait_busy();
|
||||
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN;
|
||||
|
||||
while (__REG16(I2C_BASE + I2SR) & I2SR_IBB && --timeout)
|
||||
udelay(1);
|
||||
|
||||
while (__REG16(I2C_BASE + I2SR) & I2SR_IBB && --timeout) {
|
||||
__REG16(I2C_BASE + I2SR) = 0;
|
||||
udelay(I2C_TIMEOUT_TICKET);
|
||||
}
|
||||
if (!timeout) {
|
||||
printf("%s:trigger stop fail(%x)\n",
|
||||
__func__, __REG16(I2C_BASE + I2SR));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
|
||||
{
|
||||
int timeout = 10000;
|
||||
DPRINTF("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n",__FUNCTION__, chip, addr, alen, len);
|
||||
int timeout = I2C_MAX_TIMEOUT;
|
||||
DPRINTF("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n",
|
||||
__func__, chip, addr, alen, len);
|
||||
|
||||
if (i2c_addr(chip, addr, alen))
|
||||
return -1;
|
||||
@ -194,9 +295,9 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
|
||||
__REG16(I2C_BASE + I2CR) = I2CR_IEN;
|
||||
|
||||
while (__REG16(I2C_BASE + I2SR) & I2SR_IBB && --timeout)
|
||||
udelay(1);
|
||||
udelay(I2C_TIMEOUT_TICKET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_HARD_I2C */
|
||||
#endif /* CONFIG_HARD_I2C */
|
||||
|
||||
@ -30,6 +30,7 @@ ifdef CONFIG_PS2KBD
|
||||
COBJS-y += keyboard.o pc_keyb.o
|
||||
COBJS-$(CONFIG_PS2MULT) += ps2mult.o ps2ser.o
|
||||
endif
|
||||
COBJS-${CONFIG_MXC_KPD} += mxc_keyb.o
|
||||
|
||||
COBJS := $(COBJS-y)
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
|
||||
598
drivers/input/mxc_keyb.c
Normal file
598
drivers/input/mxc_keyb.c
Normal file
@ -0,0 +1,598 @@
|
||||
/*
|
||||
* Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file mxc_keyb.c
|
||||
*
|
||||
* @brief Driver for the Freescale Semiconductor MXC keypad port.
|
||||
*
|
||||
* The keypad driver is designed as a standard Input driver which interacts
|
||||
* with low level keypad port hardware. Upon opening, the Keypad driver
|
||||
* initializes the keypad port. When the keypad interrupt happens the driver
|
||||
* calles keypad polling timer and scans the keypad matrix for key
|
||||
* press/release. If all key press/release happened it comes out of timer and
|
||||
* waits for key press interrupt. The scancode for key press and release events
|
||||
* are passed to Input subsytem.
|
||||
*
|
||||
* @ingroup keypad
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <common.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include <linux/types.h>
|
||||
#include <malloc.h>
|
||||
|
||||
/*
|
||||
* * Module header file
|
||||
* */
|
||||
#include <mxc_keyb.h>
|
||||
|
||||
/*!
|
||||
* Comment KPP_DEBUG to disable debug messages
|
||||
*/
|
||||
|
||||
#undef KPP_DEBUG
|
||||
|
||||
#ifdef KPP_DEBUG
|
||||
#define KPP_PRINTF(fmt, args...) printf(fmt , ##args)
|
||||
|
||||
static void mxc_kpp_dump_regs()
|
||||
{
|
||||
unsigned short t1, t2, t3;
|
||||
|
||||
t1 = __raw_readw(KPCR);
|
||||
t2 = __raw_readw(KPSR);
|
||||
t3 = __raw_readw(KDDR);
|
||||
/*
|
||||
KPP_PRINTF("KPCR=0x%04x, KPSR=0x%04x, KDDR=0x%04x\n",
|
||||
t1, t2, t3);
|
||||
*/
|
||||
}
|
||||
#else
|
||||
#define KPP_PRINTF(fmt, args...)
|
||||
#endif
|
||||
|
||||
static u16 mxc_key_mapping[] = CONFIG_MXC_KEYMAPPING;
|
||||
|
||||
/*!
|
||||
* This structure holds the keypad private data structure.
|
||||
*/
|
||||
static struct keypad_priv kpp_dev;
|
||||
|
||||
/*! Indicates if the key pad device is enabled. */
|
||||
|
||||
/*! This static variable indicates whether a key event is pressed/released. */
|
||||
static unsigned short KPress;
|
||||
|
||||
/*! cur_rcmap and prev_rcmap array is used to detect key press and release. */
|
||||
static unsigned short *cur_rcmap; /* max 64 bits (8x8 matrix) */
|
||||
static unsigned short *prev_rcmap;
|
||||
|
||||
/*!
|
||||
* Debounce polling period(10ms) in system ticks.
|
||||
*/
|
||||
static unsigned short KScanRate = (10 * CONFIG_SYS_HZ) / 1000;
|
||||
|
||||
/*!
|
||||
* These arrays are used to store press and release scancodes.
|
||||
*/
|
||||
static short **press_scancode;
|
||||
static short **release_scancode;
|
||||
|
||||
static const unsigned short *mxckpd_keycodes;
|
||||
static unsigned short mxckpd_keycodes_size;
|
||||
|
||||
/*!
|
||||
* These functions are used to configure and the GPIO pins for keypad to
|
||||
* activate and deactivate it.
|
||||
*/
|
||||
extern void setup_mxc_kpd(void);
|
||||
|
||||
/*!
|
||||
* This function is called to scan the keypad matrix to find out the key press
|
||||
* and key release events. Make scancode and break scancode are generated for
|
||||
* key press and key release events.
|
||||
*
|
||||
* The following scanning sequence are done for
|
||||
* keypad row and column scanning,
|
||||
* -# Write 1's to KPDR[15:8], setting column data to 1's
|
||||
* -# Configure columns as totem pole outputs(for quick discharging of keypad
|
||||
* capacitance)
|
||||
* -# Configure columns as open-drain
|
||||
* -# Write a single column to 0, others to 1.
|
||||
* -# Sample row inputs and save data. Multiple key presses can be detected on
|
||||
* a single column.
|
||||
* -# Repeat steps the above steps for remaining columns.
|
||||
* -# Return all columns to 0 in preparation for standby mode.
|
||||
* -# Clear KPKD and KPKR status bit(s) by writing to a 1,
|
||||
* Set the KPKR synchronizer chain by writing "1" to KRSS register,
|
||||
* Clear the KPKD synchronizer chain by writing "1" to KDSC register
|
||||
*
|
||||
* @result Number of key pressed/released.
|
||||
*/
|
||||
static int mxc_kpp_scan_matrix()
|
||||
{
|
||||
unsigned short reg_val;
|
||||
int col, row;
|
||||
short scancode = 0;
|
||||
int keycnt = 0; /* How many keys are still pressed */
|
||||
|
||||
/*
|
||||
* wmb() linux kernel function which guarantees orderings in write
|
||||
* operations
|
||||
*/
|
||||
/* wmb(); */
|
||||
|
||||
/* save cur keypad matrix to prev */
|
||||
memcpy(prev_rcmap, cur_rcmap, kpp_dev.kpp_rows * sizeof(prev_rcmap[0]));
|
||||
memset(cur_rcmap, 0, kpp_dev.kpp_rows * sizeof(cur_rcmap[0]));
|
||||
|
||||
for (col = 0; col < kpp_dev.kpp_cols; col++) { /* Col */
|
||||
/* 2. Write 1.s to KPDR[15:8] setting column data to 1.s */
|
||||
reg_val = __raw_readw(KPDR);
|
||||
reg_val |= 0xff00;
|
||||
__raw_writew(reg_val, KPDR);
|
||||
|
||||
/*
|
||||
* 3. Configure columns as totem pole outputs(for quick
|
||||
* discharging of keypad capacitance)
|
||||
*/
|
||||
reg_val = __raw_readw(KPCR);
|
||||
reg_val &= 0x00ff;
|
||||
__raw_writew(reg_val, KPCR);
|
||||
|
||||
udelay(2);
|
||||
|
||||
#ifdef KPP_DEBUG
|
||||
mxc_kpp_dump_regs();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 4. Configure columns as open-drain
|
||||
*/
|
||||
reg_val = __raw_readw(KPCR);
|
||||
reg_val |= ((1 << kpp_dev.kpp_cols) - 1) << 8;
|
||||
__raw_writew(reg_val, KPCR);
|
||||
|
||||
/*
|
||||
* 5. Write a single column to 0, others to 1.
|
||||
* 6. Sample row inputs and save data. Multiple key presses
|
||||
* can be detected on a single column.
|
||||
* 7. Repeat steps 2 - 6 for remaining columns.
|
||||
*/
|
||||
|
||||
/* Col bit starts at 8th bit in KPDR */
|
||||
reg_val = __raw_readw(KPDR);
|
||||
reg_val &= ~(1 << (8 + col));
|
||||
__raw_writew(reg_val, KPDR);
|
||||
|
||||
/* Delay added to avoid propagating the 0 from column to row
|
||||
* when scanning. */
|
||||
|
||||
udelay(5);
|
||||
|
||||
#ifdef KPP_DEBUG
|
||||
mxc_kpp_dump_regs();
|
||||
#endif
|
||||
|
||||
/* Read row input */
|
||||
reg_val = __raw_readw(KPDR);
|
||||
for (row = 0; row < kpp_dev.kpp_rows; row++) { /* sample row */
|
||||
if (TEST_BIT(reg_val, row) == 0) {
|
||||
cur_rcmap[row] = BITSET(cur_rcmap[row], col);
|
||||
keycnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 8. Return all columns to 0 in preparation for standby mode.
|
||||
* 9. Clear KPKD and KPKR status bit(s) by writing to a .1.,
|
||||
* set the KPKR synchronizer chain by writing "1" to KRSS register,
|
||||
* clear the KPKD synchronizer chain by writing "1" to KDSC register
|
||||
*/
|
||||
reg_val = 0x00;
|
||||
__raw_writew(reg_val, KPDR);
|
||||
reg_val = __raw_readw(KPDR);
|
||||
reg_val = __raw_readw(KPSR);
|
||||
reg_val |= KBD_STAT_KPKD | KBD_STAT_KPKR | KBD_STAT_KRSS |
|
||||
KBD_STAT_KDSC;
|
||||
__raw_writew(reg_val, KPSR);
|
||||
|
||||
#ifdef KPP_DEBUG
|
||||
mxc_kpp_dump_regs();
|
||||
#endif
|
||||
|
||||
/* Check key press status change */
|
||||
|
||||
/*
|
||||
* prev_rcmap array will contain the previous status of the keypad
|
||||
* matrix. cur_rcmap array will contains the present status of the
|
||||
* keypad matrix. If a bit is set in the array, that (row, col) bit is
|
||||
* pressed, else it is not pressed.
|
||||
*
|
||||
* XORing these two variables will give us the change in bit for
|
||||
* particular row and column. If a bit is set in XOR output, then that
|
||||
* (row, col) has a change of status from the previous state. From
|
||||
* the diff variable the key press and key release of row and column
|
||||
* are found out.
|
||||
*
|
||||
* If the key press is determined then scancode for key pressed
|
||||
* can be generated using the following statement:
|
||||
* scancode = ((row * 8) + col);
|
||||
*
|
||||
* If the key release is determined then scancode for key release
|
||||
* can be generated using the following statement:
|
||||
* scancode = ((row * 8) + col) + MXC_KEYRELEASE;
|
||||
*/
|
||||
for (row = 0; row < kpp_dev.kpp_rows; row++) {
|
||||
unsigned char diff;
|
||||
|
||||
/*
|
||||
* Calculate the change in the keypad row status
|
||||
*/
|
||||
diff = prev_rcmap[row] ^ cur_rcmap[row];
|
||||
|
||||
for (col = 0; col < kpp_dev.kpp_cols; col++) {
|
||||
if ((diff >> col) & 0x1) {
|
||||
/* There is a status change on col */
|
||||
if ((prev_rcmap[row] & BITSET(0, col)) == 0) {
|
||||
/*
|
||||
* Previous state is 0, so now
|
||||
* a key is pressed
|
||||
*/
|
||||
scancode =
|
||||
((row * kpp_dev.kpp_cols) +
|
||||
col);
|
||||
KPress = 1;
|
||||
kpp_dev.iKeyState = KStateUp;
|
||||
|
||||
KPP_PRINTF("Press (%d, %d) scan=%d "
|
||||
"Kpress=%d\n",
|
||||
row, col, scancode, KPress);
|
||||
press_scancode[row][col] =
|
||||
(short)scancode;
|
||||
} else {
|
||||
/*
|
||||
* Previous state is not 0, so
|
||||
* now a key is released
|
||||
*/
|
||||
scancode =
|
||||
(row * kpp_dev.kpp_cols) +
|
||||
col + MXC_KEYRELEASE;
|
||||
KPress = 0;
|
||||
kpp_dev.iKeyState = KStateDown;
|
||||
|
||||
KPP_PRINTF
|
||||
("Release (%d, %d) scan=%d Kpress=%d\n",
|
||||
row, col, scancode, KPress);
|
||||
release_scancode[row][col] =
|
||||
(short)scancode;
|
||||
keycnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return keycnt;
|
||||
}
|
||||
|
||||
static int mxc_kpp_reset()
|
||||
{
|
||||
unsigned short reg_val;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Stop scanning and wait for interrupt.
|
||||
* Enable press interrupt and disable release interrupt.
|
||||
*/
|
||||
__raw_writew(0x00FF, KPDR);
|
||||
reg_val = __raw_readw(KPSR);
|
||||
reg_val |= (KBD_STAT_KPKR | KBD_STAT_KPKD);
|
||||
reg_val |= KBD_STAT_KRSS | KBD_STAT_KDSC;
|
||||
__raw_writew(reg_val, KPSR);
|
||||
reg_val |= KBD_STAT_KDIE;
|
||||
reg_val &= ~KBD_STAT_KRIE;
|
||||
__raw_writew(reg_val, KPSR);
|
||||
|
||||
#ifdef KPP_DEBUG
|
||||
mxc_kpp_dump_regs();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* No more keys pressed... make sure unwanted key codes are
|
||||
* not given upstairs
|
||||
*/
|
||||
for (i = 0; i < kpp_dev.kpp_rows; i++) {
|
||||
memset(press_scancode[i], -1,
|
||||
sizeof(press_scancode[0][0]) * kpp_dev.kpp_cols);
|
||||
memset(release_scancode[i], -1,
|
||||
sizeof(release_scancode[0][0]) *
|
||||
kpp_dev.kpp_cols);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mxc_kpp_getc(struct kpp_key_info *key_info)
|
||||
{
|
||||
int col, row;
|
||||
static int key_cnt;
|
||||
unsigned short reg_val;
|
||||
short scancode = 0;
|
||||
|
||||
reg_val = __raw_readw(KPSR);
|
||||
|
||||
if (!key_cnt) {
|
||||
if (reg_val & KBD_STAT_KPKD) {
|
||||
/*
|
||||
* Disable key press(KDIE status bit) interrupt
|
||||
*/
|
||||
reg_val &= ~KBD_STAT_KDIE;
|
||||
__raw_writew(reg_val, KPSR);
|
||||
|
||||
#ifdef KPP_DEBUG
|
||||
mxc_kpp_dump_regs();
|
||||
#endif
|
||||
|
||||
key_cnt = mxc_kpp_scan_matrix();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This switch case statement is the
|
||||
* implementation of state machine of debounc
|
||||
* logic for key press/release.
|
||||
* The explaination of state machine is as
|
||||
* follows:
|
||||
*
|
||||
* KStateUp State:
|
||||
* This is in intial state of the state machine
|
||||
* this state it checks for any key presses.
|
||||
* The key press can be checked using the
|
||||
* variable KPress. If KPress is set, then key
|
||||
* press is identified and switches the to
|
||||
* KStateFirstDown state for key press to
|
||||
* debounce.
|
||||
*
|
||||
* KStateFirstDown:
|
||||
* After debounce delay(10ms), if the KPress is
|
||||
* still set then pass scancode generated to
|
||||
* input device and change the state to
|
||||
* KStateDown, else key press debounce is not
|
||||
* satisfied so change the state to KStateUp.
|
||||
*
|
||||
* KStateDown:
|
||||
* In this state it checks for any key release.
|
||||
* If KPress variable is cleared, then key
|
||||
* release is indicated and so, switch the
|
||||
* state to KStateFirstUp else to state
|
||||
* KStateDown.
|
||||
*
|
||||
* KStateFirstUp:
|
||||
* After debounce delay(10ms), if the KPress is
|
||||
* still reset then pass the key release
|
||||
* scancode to input device and change
|
||||
* the state to KStateUp else key release is
|
||||
* not satisfied so change the state to
|
||||
* KStateDown.
|
||||
*/
|
||||
|
||||
for (row = 0; row < kpp_dev.kpp_rows; row++) {
|
||||
for (col = 0; col < kpp_dev.kpp_cols; col++) {
|
||||
if ((press_scancode[row][col] != -1)) {
|
||||
/* Still Down, so add scancode */
|
||||
scancode =
|
||||
press_scancode[row][col];
|
||||
|
||||
key_info->val = mxckpd_keycodes[scancode];
|
||||
key_info->evt = KDepress;
|
||||
|
||||
KPP_PRINTF("KStateFirstDown: scan=%d val=%d\n",
|
||||
scancode, mxckpd_keycodes[scancode]);
|
||||
kpp_dev.iKeyState = KStateDown;
|
||||
press_scancode[row][col] = -1;
|
||||
|
||||
goto key_detect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (row = 0; row < kpp_dev.kpp_rows; row++) {
|
||||
for (col = 0; col < kpp_dev.kpp_cols; col++) {
|
||||
if ((release_scancode[row][col] != -1)) {
|
||||
scancode =
|
||||
release_scancode[row][col];
|
||||
scancode =
|
||||
scancode - MXC_KEYRELEASE;
|
||||
|
||||
key_info->val = mxckpd_keycodes[scancode];
|
||||
key_info->evt = KRelease;
|
||||
|
||||
KPP_PRINTF("KStateFirstUp: scan=%d val=%d\n",
|
||||
scancode, mxckpd_keycodes[scancode]);
|
||||
|
||||
kpp_dev.iKeyState = KStateUp;
|
||||
release_scancode[row][col] = -1;
|
||||
|
||||
goto key_detect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
key_detect:
|
||||
/* udelay(KScanRate); */
|
||||
key_cnt = mxc_kpp_scan_matrix();
|
||||
|
||||
if (0 == key_cnt)
|
||||
mxc_kpp_reset();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function is called to free the allocated memory for local arrays
|
||||
*/
|
||||
static void mxc_kpp_free_allocated(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (press_scancode) {
|
||||
for (i = 0; i < kpp_dev.kpp_rows; i++) {
|
||||
if (press_scancode[i])
|
||||
free(press_scancode[i]);
|
||||
}
|
||||
free(press_scancode);
|
||||
}
|
||||
|
||||
if (release_scancode) {
|
||||
for (i = 0; i < kpp_dev.kpp_rows; i++) {
|
||||
if (release_scancode[i])
|
||||
free(release_scancode[i]);
|
||||
}
|
||||
free(release_scancode);
|
||||
}
|
||||
|
||||
if (cur_rcmap)
|
||||
free(cur_rcmap);
|
||||
|
||||
if (prev_rcmap)
|
||||
free(prev_rcmap);
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function is called during the driver binding process.
|
||||
*
|
||||
* @param pdev the device structure used to store device specific
|
||||
* information that is used by the suspend, resume and remove
|
||||
* functions.
|
||||
*
|
||||
* @return The function returns 0 on successful registration. Otherwise returns
|
||||
* specific error code.
|
||||
*/
|
||||
int mxc_kpp_init()
|
||||
{
|
||||
int i;
|
||||
int retval;
|
||||
unsigned int reg_val;
|
||||
|
||||
kpp_dev.kpp_cols = CONFIG_MXC_KPD_COLMAX;
|
||||
kpp_dev.kpp_rows = CONFIG_MXC_KPD_ROWMAX;
|
||||
|
||||
/* clock and IOMUX configuration for keypad */
|
||||
setup_mxc_kpd();
|
||||
|
||||
/* Configure keypad */
|
||||
|
||||
/* Enable number of rows in keypad (KPCR[7:0])
|
||||
* Configure keypad columns as open-drain (KPCR[15:8])
|
||||
*
|
||||
* Configure the rows/cols in KPP
|
||||
* LSB nibble in KPP is for 8 rows
|
||||
* MSB nibble in KPP is for 8 cols
|
||||
*/
|
||||
reg_val = __raw_readw(KPCR);
|
||||
reg_val |= (1 << kpp_dev.kpp_rows) - 1; /* LSB */
|
||||
reg_val |= ((1 << kpp_dev.kpp_cols) - 1) << 8; /* MSB */
|
||||
__raw_writew(reg_val, KPCR);
|
||||
|
||||
/* Write 0's to KPDR[15:8] */
|
||||
reg_val = __raw_readw(KPDR);
|
||||
reg_val &= 0x00ff;
|
||||
__raw_writew(reg_val, KPDR);
|
||||
|
||||
/* Configure columns as output,
|
||||
* rows as input (KDDR[15:0]) */
|
||||
reg_val = __raw_readw(KDDR);
|
||||
reg_val |= 0xff00;
|
||||
reg_val &= 0xff00;
|
||||
__raw_writew(reg_val, KDDR);
|
||||
|
||||
/* Clear the KPKD Status Flag
|
||||
* and Synchronizer chain. */
|
||||
reg_val = __raw_readw(KPSR);
|
||||
reg_val &= ~(KBD_STAT_KPKR | KBD_STAT_KPKD);
|
||||
reg_val |= KBD_STAT_KPKD;
|
||||
reg_val |= KBD_STAT_KRSS | KBD_STAT_KDSC;
|
||||
__raw_writew(reg_val, KPSR);
|
||||
/* Set the KDIE control bit, and clear the KRIE
|
||||
* control bit (avoid false release events). */
|
||||
reg_val |= KBD_STAT_KDIE;
|
||||
reg_val &= ~KBD_STAT_KRIE;
|
||||
__raw_writew(reg_val, KPSR);
|
||||
|
||||
#ifdef KPP_DEBUG
|
||||
mxc_kpp_dump_regs();
|
||||
#endif
|
||||
|
||||
mxckpd_keycodes = mxc_key_mapping;
|
||||
mxckpd_keycodes_size = kpp_dev.kpp_cols * kpp_dev.kpp_rows;
|
||||
|
||||
if ((mxckpd_keycodes == (void *)0)
|
||||
|| (mxckpd_keycodes_size == 0)) {
|
||||
retval = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* allocate required memory */
|
||||
press_scancode = (short **)malloc(kpp_dev.kpp_rows * sizeof(press_scancode[0]));
|
||||
release_scancode = (short **)malloc(kpp_dev.kpp_rows * sizeof(release_scancode[0]));
|
||||
|
||||
if (!press_scancode || !release_scancode) {
|
||||
retval = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < kpp_dev.kpp_rows; i++) {
|
||||
press_scancode[i] = (short *)malloc(kpp_dev.kpp_cols
|
||||
* sizeof(press_scancode[0][0]));
|
||||
release_scancode[i] =
|
||||
(short *)malloc(kpp_dev.kpp_cols * sizeof(release_scancode[0][0]));
|
||||
|
||||
if (!press_scancode[i] || !release_scancode[i]) {
|
||||
retval = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
cur_rcmap =
|
||||
(unsigned short *)malloc(kpp_dev.kpp_rows * sizeof(cur_rcmap[0]));
|
||||
prev_rcmap =
|
||||
(unsigned short *)malloc(kpp_dev.kpp_rows * sizeof(prev_rcmap[0]));
|
||||
|
||||
if (!cur_rcmap || !prev_rcmap) {
|
||||
retval = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < kpp_dev.kpp_rows; i++) {
|
||||
memset(press_scancode[i], -1,
|
||||
sizeof(press_scancode[0][0]) * kpp_dev.kpp_cols);
|
||||
memset(release_scancode[i], -1,
|
||||
sizeof(release_scancode[0][0]) * kpp_dev.kpp_cols);
|
||||
}
|
||||
memset(cur_rcmap, 0, kpp_dev.kpp_rows * sizeof(cur_rcmap[0]));
|
||||
memset(prev_rcmap, 0, kpp_dev.kpp_rows * sizeof(prev_rcmap[0]));
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
mxc_kpp_free_allocated();
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -26,6 +26,8 @@ include $(TOPDIR)/config.mk
|
||||
LIB := $(obj)libmmc.a
|
||||
|
||||
COBJS-$(CONFIG_ATMEL_MCI) += atmel_mci.o
|
||||
COBJS-$(CONFIG_FSL_MMC) += fsl_mmc.o
|
||||
COBJS-$(CONFIG_FSL_MMC) += fsl_esdhc.o
|
||||
|
||||
COBJS := $(COBJS-y)
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
|
||||
630
drivers/mmc/fsl_esdhc.c
Normal file
630
drivers/mmc/fsl_esdhc.c
Normal file
@ -0,0 +1,630 @@
|
||||
/*
|
||||
* Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file esdhc.c
|
||||
*
|
||||
* @brief source code for the mmc card operation
|
||||
*
|
||||
* @ingroup mmc
|
||||
*/
|
||||
|
||||
#include <asm/fsl_esdhc.h>
|
||||
#include <linux/mmc/sdhci.h>
|
||||
#include <asm/errno.h>
|
||||
#include <common.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#ifdef CONFIG_MMC
|
||||
|
||||
#define RETRIES_TIMES 100
|
||||
|
||||
#define REG_WRITE_OR(val, reg) { \
|
||||
u32 temp = 0; \
|
||||
temp = readl(reg); \
|
||||
(temp) |= (val); \
|
||||
writel((temp), (reg)); \
|
||||
}
|
||||
|
||||
#define REG_WRITE_AND(val, reg) { \
|
||||
u32 temp = 0; \
|
||||
temp = readl(reg); \
|
||||
(temp) &= (val); \
|
||||
writel((temp), (reg)); \
|
||||
}
|
||||
|
||||
#define SDHC_DELAY_BY_100(x) { \
|
||||
u32 i; \
|
||||
for (i = 0; i < x; ++i) \
|
||||
udelay(100); \
|
||||
}
|
||||
|
||||
|
||||
extern volatile u32 esdhc_base_pointer;
|
||||
|
||||
static void esdhc_cmd_config(esdhc_cmd_t *);
|
||||
static u32 esdhc_check_response(void);
|
||||
static u32 esdhc_wait_buf_rdy_intr(u32, u32);
|
||||
static void esdhc_wait_op_done_intr(void);
|
||||
static u32 esdhc_check_data(void);
|
||||
static void esdhc_set_data_transfer_width(u32 data_transfer_width);
|
||||
static u32 esdhc_poll_cihb_cdihb(data_present_select data_present);
|
||||
static void esdhc_set_endianness(u32 endian_mode);
|
||||
static void esdhc_clear_buf_rdy_intr(u32 mask);
|
||||
static u32 esdhc_check_data_crc_status(void);
|
||||
|
||||
/*!
|
||||
* Send 80 SD clock to card and wait for INITA bit to get cleared.
|
||||
*/
|
||||
void interface_initialization_active(void)
|
||||
{
|
||||
/* Send 80 clock ticks for card to power up */
|
||||
REG_WRITE_OR(ESDHC_SYSCTL_INITA, \
|
||||
esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
|
||||
|
||||
/* Start a general purpose timer */
|
||||
udelay(ESDHC_CARD_INIT_TIMEOUT);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Execute a software reset and set data bus width for eSDHC.
|
||||
*/
|
||||
u32 interface_reset()
|
||||
{
|
||||
u32 reset_status = 0;
|
||||
u32 u32Retries = 0;
|
||||
u32 u32Temp = 0;
|
||||
|
||||
debug("Entry: interface_reset");
|
||||
|
||||
/* Reset the entire host controller by writing
|
||||
1 to RSTA bit of SYSCTRL Register */
|
||||
REG_WRITE_OR(ESDHC_SOFTWARE_RESET, \
|
||||
esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
|
||||
|
||||
/* Start a general purpose timer (3 millsec delay) */
|
||||
/* udelay(ESDHC_OPER_TIMEOUT); */
|
||||
|
||||
/* Wait for clearance of CIHB and CDIHB Bits */
|
||||
for (u32Retries = RETRIES_TIMES; u32Retries > 0; --u32Retries) {
|
||||
if (readl(esdhc_base_pointer + SDHCI_SYSTEM_CONTROL) \
|
||||
& ESDHC_SOFTWARE_RESET) {
|
||||
reset_status = 1;
|
||||
} else {
|
||||
reset_status = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set data bus width of ESDCH */
|
||||
esdhc_set_data_transfer_width(0x00000000);
|
||||
|
||||
/* Set Endianness of ESDHC */
|
||||
esdhc_set_endianness(0x00000020);
|
||||
|
||||
/* set data timeout delay to max */
|
||||
u32Temp = (readl(esdhc_base_pointer + SDHCI_SYSTEM_CONTROL) & \
|
||||
0xfff0ffff) | 0x000e0000;
|
||||
writel(u32Temp, esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
|
||||
|
||||
return reset_status;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Clear interrupts at eSDHC level.
|
||||
*/
|
||||
void interface_clear_interrupt(void)
|
||||
{
|
||||
/* Clear Interrupt status register */
|
||||
writel(ESDHC_CLEAR_INTERRUPT, esdhc_base_pointer + SDHCI_INT_STATUS);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Enable Clock and set operating frequency.
|
||||
*/
|
||||
void interface_configure_clock(sdhc_freq_t frequency)
|
||||
{
|
||||
u32 ident_freq = 0;
|
||||
u32 oper_freq = 0;
|
||||
|
||||
/* Clear SDCLKEN bit */
|
||||
REG_WRITE_AND((~ESDHC_SYSCTL_SDCLKEN_MASK), \
|
||||
esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
|
||||
|
||||
/* Clear DTOCV, SDCLKFS, DVFS bits */
|
||||
REG_WRITE_AND((~ESDHC_SYSCTL_FREQ_MASK), \
|
||||
esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
|
||||
ident_freq = ESDHC_SYSCTL_IDENT_FREQ;
|
||||
oper_freq = ESDHC_SYSCTL_OPERT_FREQ;
|
||||
|
||||
/* Disable the PEREN, HCKEN and IPGEN */
|
||||
REG_WRITE_AND((~ESDHC_SYSCTL_INPUT_CLOCK_MASK), \
|
||||
esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
|
||||
|
||||
if (frequency == IDENTIFICATION_FREQ) {
|
||||
/* Input frequecy to eSDHC is 36 MHZ */
|
||||
/* PLL3 is the source of input frequency*/
|
||||
/*Set DTOCV and SDCLKFS bit to get SD_CLK
|
||||
of frequency below 400 KHZ (70.31 KHZ) */
|
||||
REG_WRITE_OR(ident_freq, \
|
||||
esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
|
||||
} else if (frequency == OPERATING_FREQ) {
|
||||
/*Set DTOCV and SDCLKFS bit to get SD_CLK
|
||||
of frequency around 25 MHz.(18 MHz)*/
|
||||
REG_WRITE_OR(oper_freq, \
|
||||
esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
|
||||
}
|
||||
|
||||
/* Start a general purpose timer */
|
||||
/* Wait for clock to be stable */
|
||||
SDHC_DELAY_BY_100(96);
|
||||
|
||||
/* Set SDCLKEN bit to enable clock */
|
||||
REG_WRITE_OR(ESDHC_SYSCTL_SDCLKEN_MASK, \
|
||||
esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
|
||||
|
||||
/* Mask Data Timeout Error Status Enable Interrupt (DTOESEN) */
|
||||
REG_WRITE_AND((~ESDHC_IRQSTATEN_DTOESEN), \
|
||||
esdhc_base_pointer + SDHCI_INT_ENABLE);
|
||||
|
||||
/* Set the Data Timeout Counter Value(DTOCV) */
|
||||
REG_WRITE_OR(ESDHC_SYSCTL_DTOCV_VAL, \
|
||||
esdhc_base_pointer + SDHCI_SYSTEM_CONTROL);
|
||||
|
||||
/* Enable Data Timeout Error Status
|
||||
Enable Interrupt (DTOESEN) */
|
||||
REG_WRITE_OR(ESDHC_IRQSTATEN_DTOESEN, \
|
||||
esdhc_base_pointer + SDHCI_INT_ENABLE);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Set data transfer width for e-SDHC.
|
||||
*/
|
||||
static void esdhc_set_data_transfer_width(u32 data_transfer_width)
|
||||
{
|
||||
|
||||
/* Set DWT bit of protocol control register according to bus_width */
|
||||
REG_WRITE_AND((~ESDHC_BUS_WIDTH_MASK), \
|
||||
esdhc_base_pointer + SDHCI_HOST_CONTROL);
|
||||
|
||||
REG_WRITE_OR((data_transfer_width), \
|
||||
esdhc_base_pointer + SDHCI_HOST_CONTROL);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Set endianness mode for e-SDHC.
|
||||
*/
|
||||
static void esdhc_set_endianness(u32 endian_mode)
|
||||
{
|
||||
REG_WRITE_AND((~ESDHC_ENDIAN_MODE_MASK), \
|
||||
esdhc_base_pointer + SDHCI_HOST_CONTROL);
|
||||
/* Set DWT bit of protocol control register according to bus_width */
|
||||
REG_WRITE_OR((endian_mode), \
|
||||
esdhc_base_pointer + SDHCI_HOST_CONTROL);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Poll the CIHB & CDIHB bits of the present
|
||||
* state register and wait until it goes low.
|
||||
*/
|
||||
static u32 esdhc_poll_cihb_cdihb(data_present_select data_present)
|
||||
{
|
||||
u32 init_status = 0;
|
||||
u32 u32Retries = 0;
|
||||
|
||||
/* Start a general purpose timer */
|
||||
for (u32Retries = RETRIES_TIMES; u32Retries > 0; u32Retries--) {
|
||||
if (!(readl(esdhc_base_pointer + SDHCI_PRESENT_STATE) & \
|
||||
ESDHC_PRESENT_STATE_CIHB)) {
|
||||
init_status = 0;
|
||||
break;
|
||||
}
|
||||
SDHC_DELAY_BY_100(10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for the data line to be free (poll the CDIHB bit of
|
||||
* the present state register).
|
||||
*/
|
||||
if ((0 == init_status) && (data_present == DATA_PRESENT)) {
|
||||
/* Start a general purpose timer */
|
||||
SDHC_DELAY_BY_100(32);
|
||||
|
||||
if (readl(esdhc_base_pointer + SDHCI_PRESENT_STATE) & \
|
||||
ESDHC_PRESENT_STATE_CDIHB) {
|
||||
init_status = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return init_status;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Wait until the command and data lines are free.
|
||||
*/
|
||||
u32 interface_wait_cmd_data_lines(data_present_select data_present)
|
||||
{
|
||||
u32 cmd_status = 0;
|
||||
|
||||
cmd_status = esdhc_poll_cihb_cdihb(data_present);
|
||||
|
||||
return cmd_status;
|
||||
}
|
||||
|
||||
u32 interface_set_bus_width(u32 bus_width)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
tmp = readl(esdhc_base_pointer + SDHCI_HOST_CONTROL);
|
||||
|
||||
tmp &= ~SDHCI_CTRL_8BITBUS;
|
||||
tmp |= SDHCI_CTRL_4BITBUS;
|
||||
|
||||
writel(tmp, esdhc_base_pointer + SDHCI_HOST_CONTROL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Execute a command and wait for the response.
|
||||
*/
|
||||
u32 interface_send_cmd_wait_resp(esdhc_cmd_t *cmd)
|
||||
{
|
||||
u32 cmd_status = 0;
|
||||
|
||||
/* Clear Interrupt status register */
|
||||
writel(ESDHC_CLEAR_INTERRUPT, \
|
||||
esdhc_base_pointer + SDHCI_INT_STATUS);
|
||||
|
||||
/* Enable Interrupt */
|
||||
REG_WRITE_OR(ESDHC_INTERRUPT_ENABLE, \
|
||||
esdhc_base_pointer + SDHCI_INT_ENABLE);
|
||||
|
||||
cmd_status = interface_wait_cmd_data_lines(cmd->data_present);
|
||||
|
||||
if (cmd_status == 1)
|
||||
return 1;
|
||||
|
||||
/* Configure Command */
|
||||
esdhc_cmd_config(cmd);
|
||||
|
||||
/* Wait for interrupt CTOE or CC */
|
||||
SDHC_DELAY_BY_100(96);
|
||||
|
||||
/* Mask all interrupts */
|
||||
writel(0, esdhc_base_pointer + SDHCI_SIGNAL_ENABLE);
|
||||
|
||||
/* Check if an error occured */
|
||||
return esdhc_check_response();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Configure ESDHC registers for sending a command to MMC.
|
||||
*/
|
||||
static void esdhc_cmd_config(esdhc_cmd_t *cmd)
|
||||
{
|
||||
u32 u32Temp = 0;
|
||||
|
||||
/* Write Command Argument in Command Argument Register */
|
||||
writel(cmd->arg, esdhc_base_pointer + SDHCI_ARGUMENT);
|
||||
|
||||
/*
|
||||
*Configure e-SDHC Register value according to Command
|
||||
*/
|
||||
u32Temp = \
|
||||
(((cmd->data_transfer)<<ESDHC_DATA_TRANSFER_SHIFT) |
|
||||
((cmd->response_format)<<ESDHC_RESPONSE_FORMAT_SHIFT) |
|
||||
((cmd->data_present)<<ESDHC_DATA_PRESENT_SHIFT) |
|
||||
((cmd->crc_check) << ESDHC_CRC_CHECK_SHIFT) |
|
||||
((cmd->cmdindex_check) << ESDHC_CMD_INDEX_CHECK_SHIFT) |
|
||||
((cmd->command) << ESDHC_CMD_INDEX_SHIFT) |
|
||||
((cmd->block_count_enable_check) << \
|
||||
ESDHC_BLOCK_COUNT_ENABLE_SHIFT) |
|
||||
((cmd->multi_single_block) << \
|
||||
ESDHC_MULTI_SINGLE_BLOCK_SELECT_SHIFT));
|
||||
|
||||
writel(u32Temp, esdhc_base_pointer + SDHCI_TRANSFER_MODE);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Wait a END_CMD_RESP interrupt by interrupt status register.
|
||||
* e-SDHC sets this bit after receving command response.
|
||||
*/
|
||||
static u32 esdhc_check_response(void)
|
||||
{
|
||||
u32 status = 1;
|
||||
|
||||
/* Check whether the interrupt is an END_CMD_RESP
|
||||
* or a response time out or a CRC error
|
||||
*/
|
||||
if ((readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
|
||||
ESDHC_STATUS_END_CMD_RESP_MSK) &&
|
||||
!(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
|
||||
ESDHC_STATUS_TIME_OUT_RESP_MSK) &&
|
||||
!(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
|
||||
ESDHC_STATUS_RESP_CRC_ERR_MSK) &&
|
||||
!(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
|
||||
ESDHC_STATUS_RESP_CMD_INDEX_ERR_MSK))
|
||||
status = 0;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function will read response from e-SDHC
|
||||
* register according to reponse format.
|
||||
*/
|
||||
void interface_read_response(esdhc_resp_t *cmd_resp)
|
||||
{
|
||||
/* get response values from e-SDHC CMDRSP registers.*/
|
||||
cmd_resp->cmd_rsp0 = (u32)readl(esdhc_base_pointer + SDHCI_RESPONSE);
|
||||
cmd_resp->cmd_rsp1 = (u32)readl(esdhc_base_pointer + \
|
||||
SDHCI_RESPONSE + 4);
|
||||
cmd_resp->cmd_rsp2 = (u32)readl(esdhc_base_pointer + \
|
||||
SDHCI_RESPONSE + 8);
|
||||
cmd_resp->cmd_rsp3 = (u32)readl(esdhc_base_pointer + \
|
||||
SDHCI_RESPONSE + 12);
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function will read response from e-SDHC register
|
||||
* according to reponse format.
|
||||
*/
|
||||
u32 interface_data_read(u32 *dest_ptr, u32 blk_len)
|
||||
{
|
||||
u32 i = 0;
|
||||
u32 j = 0;
|
||||
u32 status = 1;
|
||||
u32 *tmp_ptr = dest_ptr;
|
||||
|
||||
debug("Entry: interface_data_read()\n");
|
||||
|
||||
/* Enable Interrupt */
|
||||
REG_WRITE_OR(ESDHC_INTERRUPT_ENABLE, \
|
||||
esdhc_base_pointer + SDHCI_INT_ENABLE);
|
||||
|
||||
for (i = 0; i < (blk_len) / (ESDHC_FIFO_SIZE * 4); ++i) {
|
||||
/* Wait for BRR bit to be set */
|
||||
status = esdhc_wait_buf_rdy_intr(ESDHC_STATUS_BUF_READ_RDY_MSK,
|
||||
ESDHC_READ_DATA_TIME_OUT);
|
||||
|
||||
debug("esdhc_wait_buf_rdy_intr: %d\n", status);
|
||||
|
||||
if (!status) {
|
||||
for (j = 0; j < ESDHC_FIFO_SIZE; ++j) {
|
||||
*tmp_ptr++ = \
|
||||
readl(esdhc_base_pointer + SDHCI_BUFFER);
|
||||
}
|
||||
/* Clear the BRR */
|
||||
esdhc_clear_buf_rdy_intr(ESDHC_STATUS_BUF_READ_RDY_MSK);
|
||||
} else {
|
||||
debug("esdhc_wait_buf_rdy_intr failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
esdhc_wait_op_done_intr();
|
||||
|
||||
status = esdhc_check_data();
|
||||
|
||||
if (!status)
|
||||
status = 0;
|
||||
|
||||
debug("esdhc_check_data: %d\n", status);
|
||||
|
||||
debug("Exit: interface_data_read()\n");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Wait a BUF_READ_READY interrupt by pooling STATUS register.
|
||||
*/
|
||||
static u32 esdhc_wait_buf_rdy_intr(u32 mask, u32 multi_single_block)
|
||||
{
|
||||
u32 status = 0;
|
||||
u32 u32Retries = 0;
|
||||
|
||||
/* Wait interrupt (BUF_READ_RDY)
|
||||
*/
|
||||
|
||||
for (u32Retries = RETRIES_TIMES; u32Retries > 0; --u32Retries) {
|
||||
if (!(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & mask)) {
|
||||
status = 1;
|
||||
} else {
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
SDHC_DELAY_BY_100(10);
|
||||
}
|
||||
|
||||
if (multi_single_block == MULTIPLE && \
|
||||
readl(esdhc_base_pointer + SDHCI_INT_STATUS) & mask)
|
||||
REG_WRITE_OR(mask, (esdhc_base_pointer + SDHCI_INT_STATUS));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Clear BUF_READ_READY/BUF_WRITE_READY interrupt
|
||||
* by writing 1 to STATUS register.
|
||||
*/
|
||||
static void esdhc_clear_buf_rdy_intr(u32 mask)
|
||||
{
|
||||
writel(mask, (esdhc_base_pointer + SDHCI_INT_STATUS));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Wait for TC, DEBE, DCE or DTOE by polling Interrupt STATUS register.
|
||||
*/
|
||||
static void esdhc_wait_op_done_intr(void)
|
||||
{
|
||||
while (!(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
|
||||
ESDHC_STATUS_TRANSFER_COMPLETE_MSK))
|
||||
;
|
||||
}
|
||||
|
||||
/*!
|
||||
* If READ_OP_DONE occured check ESDHC_STATUS_TIME_OUT_READ
|
||||
* and RD_CRC_ERR_CODE and
|
||||
* to determine if an error occured
|
||||
*/
|
||||
static u32 esdhc_check_data(void)
|
||||
{
|
||||
|
||||
u32 status = 1;
|
||||
|
||||
debug("Entry: esdhc_check_data()\n");
|
||||
|
||||
/* Check whether the interrupt is an OP_DONE
|
||||
* or a data time out or a CRC error
|
||||
*/
|
||||
if ((readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
|
||||
ESDHC_STATUS_TRANSFER_COMPLETE_MSK) &&
|
||||
!(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
|
||||
ESDHC_STATUS_TIME_OUT_READ_MASK) &&
|
||||
!(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
|
||||
ESDHC_STATUS_READ_CRC_ERR_MSK)) {
|
||||
writel(ESDHC_STATUS_TRANSFER_COMPLETE_MSK, \
|
||||
(esdhc_base_pointer + SDHCI_INT_STATUS));
|
||||
status = 0;
|
||||
} else {
|
||||
status = 1;
|
||||
}
|
||||
|
||||
debug("Exit: esdhc_check_data()\n");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Check for Data timeout error, data CRC error and data end bit error
|
||||
* to determine if an error occured.
|
||||
*/
|
||||
static u32 esdhc_check_data_crc_status(void)
|
||||
{
|
||||
u32 status = 1;
|
||||
|
||||
/* Check whether the interrupt is DTOE/DCE/DEBE */
|
||||
if (!(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
|
||||
ESDHC_STATUS_TIME_OUT_READ_MASK) &&
|
||||
!(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
|
||||
ESDHC_STATUS_READ_CRC_ERR_MSK) &&
|
||||
!(readl(esdhc_base_pointer + SDHCI_INT_STATUS) & \
|
||||
ESDHC_STATUS_RW_DATA_END_BIT_ERR_MSK)) {
|
||||
status = 0;
|
||||
} else {
|
||||
status = 1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Set Block length.
|
||||
*/
|
||||
void interface_config_block_info(u32 blk_len, u32 nob, u32 wml)
|
||||
{
|
||||
/* Configre block Attributes register */
|
||||
writel(((nob << ESDHC_BLOCK_SHIFT) | blk_len), \
|
||||
(esdhc_base_pointer + SDHCI_BLOCK_SIZE));
|
||||
|
||||
/* Set Read Water MArk Level register */
|
||||
writel(wml, esdhc_base_pointer + SDHCI_WML_LEV);
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function will write data to device attached to interface.
|
||||
*/
|
||||
u32 interface_data_write(u32 *dest_ptr, u32 blk_len)
|
||||
{
|
||||
u32 i = 0;
|
||||
u32 j = 0;
|
||||
u32 status = 1;
|
||||
u32 *tmp_ptr = dest_ptr;
|
||||
|
||||
debug("Entry: interface_data_write()\n");
|
||||
|
||||
/* Enable Interrupt */
|
||||
REG_WRITE_OR(ESDHC_INTERRUPT_ENABLE, \
|
||||
(esdhc_base_pointer + SDHCI_INT_ENABLE));
|
||||
|
||||
for (i = 0; i < (blk_len) / (ESDHC_FIFO_SIZE * 4); ++i) {
|
||||
/* Wait for BWR bit to be set */
|
||||
esdhc_wait_buf_rdy_intr(ESDHC_STATUS_BUF_WRITE_RDY_MSK, \
|
||||
SINGLE);
|
||||
|
||||
for (j = 0; j < ESDHC_FIFO_SIZE; ++j) {
|
||||
writel((*tmp_ptr), esdhc_base_pointer + SDHCI_BUFFER);
|
||||
++tmp_ptr;
|
||||
}
|
||||
esdhc_clear_buf_rdy_intr(ESDHC_STATUS_BUF_WRITE_RDY_MSK);
|
||||
}
|
||||
|
||||
/* Wait for transfer complete operation interrupt */
|
||||
esdhc_wait_op_done_intr();
|
||||
|
||||
/* Check for status errors */
|
||||
status = esdhc_check_data();
|
||||
|
||||
debug("Exit: interface_data_write()\n");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Configure the CMD line PAD configuration for strong or weak pull-up.
|
||||
*/
|
||||
/*
|
||||
void esdhc_set_cmd_pullup(esdhc_pullup_t pull_up)
|
||||
{
|
||||
u32 interface_esdhc = 0;
|
||||
u32 pad_val = 0;
|
||||
|
||||
interface_esdhc = (readl(0x53ff080c)) & (0x000000C0) >> 6;
|
||||
|
||||
if (pull_up == STRONG) {
|
||||
pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
|
||||
PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_HIGH |
|
||||
PAD_CTL_22K_PU | PAD_CTL_SRE_FAST;
|
||||
} else {
|
||||
pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
|
||||
PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_MAX |
|
||||
PAD_CTL_100K_PU | PAD_CTL_SRE_FAST;
|
||||
}
|
||||
|
||||
switch (interface_esdhc) {
|
||||
case ESDHC1:
|
||||
mxc_iomux_set_pad(MX51_PIN_SD1_CMD, pad_val);
|
||||
break;
|
||||
case ESDHC2:
|
||||
mxc_iomux_set_pad(MX51_PIN_SD2_CMD, pad_val);
|
||||
break;
|
||||
case ESDHC3:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#endif
|
||||
1569
drivers/mmc/fsl_mmc.c
Normal file
1569
drivers/mmc/fsl_mmc.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -38,6 +38,9 @@ endif
|
||||
COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
|
||||
COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o
|
||||
COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o
|
||||
COBJS-$(CONFIG_MX25) += mxc_nand.o
|
||||
COBJS-$(CONFIG_MX31_NAND) += mx31_nand.o
|
||||
COBJS-$(CONFIG_MXC_NAND) += mxc_nand.o
|
||||
endif
|
||||
|
||||
COBJS := $(COBJS-y)
|
||||
|
||||
968
drivers/mtd/nand/mx31_nand.c
Normal file
968
drivers/mtd/nand/mx31_nand.c
Normal file
@ -0,0 +1,968 @@
|
||||
/*
|
||||
* Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <nand.h>
|
||||
#include <asm-arm/arch/mx31-regs.h>
|
||||
|
||||
/*
|
||||
* Define delays in microsec for NAND device operations
|
||||
*/
|
||||
#define TROP_US_DELAY 2000
|
||||
|
||||
/*
|
||||
* Macros to get byte and bit positions of ECC
|
||||
*/
|
||||
#define COLPOS(x) ((x) >> 4)
|
||||
#define BITPOS(x) ((x) & 0xf)
|
||||
|
||||
/* Define single bit Error positions in Main & Spare area */
|
||||
#define MAIN_SINGLEBIT_ERROR 0x4
|
||||
#define SPARE_SINGLEBIT_ERROR 0x1
|
||||
|
||||
struct nand_info {
|
||||
int oob;
|
||||
int read_status;
|
||||
int largepage;
|
||||
u16 col;
|
||||
};
|
||||
|
||||
static struct nand_info nandinfo;
|
||||
static int ecc_disabled;
|
||||
|
||||
/*
|
||||
* OOB placement block for use with hardware ecc generation
|
||||
*/
|
||||
static struct nand_ecclayout nand_hw_eccoob_8 = {
|
||||
.eccbytes = 5,
|
||||
.eccpos = {6, 7, 8, 9, 10},
|
||||
.oobfree = {
|
||||
{0, 5},
|
||||
{11, 5}
|
||||
}
|
||||
};
|
||||
|
||||
static struct nand_ecclayout nand_hw_eccoob_2k = {
|
||||
.eccbytes = 20,
|
||||
.eccpos = {6, 7, 8, 9, 10, 22, 23, 24, 25, 26,
|
||||
38, 39, 40, 41, 42, 54, 55, 56, 57, 58},
|
||||
.oobfree = {
|
||||
{0, 5},
|
||||
{11, 10},
|
||||
{27, 10},
|
||||
{43, 10},
|
||||
{59, 5}
|
||||
}
|
||||
};
|
||||
|
||||
/* Define some generic bad / good block scan pattern which are used
|
||||
* while scanning a device for factory marked good / bad blocks. */
|
||||
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
|
||||
|
||||
static struct nand_bbt_descr smallpage_memorybased = {
|
||||
.options = NAND_BBT_SCAN2NDPAGE,
|
||||
.offs = 5,
|
||||
.len = 1,
|
||||
.pattern = scan_ff_pattern
|
||||
};
|
||||
|
||||
static struct nand_bbt_descr largepage_memorybased = {
|
||||
.options = 0,
|
||||
.offs = 0,
|
||||
.len = 2,
|
||||
.pattern = scan_ff_pattern
|
||||
};
|
||||
|
||||
/* Generic flash bbt decriptors */
|
||||
static uint8_t bbt_pattern[] = { 'B', 'b', 't', '0' };
|
||||
static uint8_t mirror_pattern[] = { '1', 't', 'b', 'B' };
|
||||
|
||||
static struct nand_bbt_descr bbt_main_descr = {
|
||||
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
|
||||
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
|
||||
.offs = 0,
|
||||
.len = 4,
|
||||
.veroffs = 4,
|
||||
.maxblocks = 4,
|
||||
.pattern = bbt_pattern
|
||||
};
|
||||
|
||||
static struct nand_bbt_descr bbt_mirror_descr = {
|
||||
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
|
||||
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
|
||||
.offs = 0,
|
||||
.len = 4,
|
||||
.veroffs = 4,
|
||||
.maxblocks = 4,
|
||||
.pattern = mirror_pattern
|
||||
};
|
||||
|
||||
/**
|
||||
* memcpy variant that copies 32 bit words. This is needed since the
|
||||
* NFC only allows 32 bit accesses. Added for U-boot.
|
||||
*/
|
||||
static void *memcpy_32(void *dest, const void *src, size_t n)
|
||||
{
|
||||
u32 *dst_32 = (u32 *) dest;
|
||||
const u32 *src_32 = (u32 *) src;
|
||||
|
||||
while (n > 0) {
|
||||
*dst_32++ = *src_32++;
|
||||
n -= 4;
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function polls the NANDFC to wait for the basic operation to
|
||||
* complete by checking the INT bit of config2 register.
|
||||
*
|
||||
* @param max_retries number of retry attempts (separated by 1 us)
|
||||
*/
|
||||
static void wait_op_done(int max_retries)
|
||||
{
|
||||
while (max_retries-- > 0) {
|
||||
if (NFC_CONFIG2 & NFC_INT) {
|
||||
NFC_CONFIG2 &= ~NFC_INT;
|
||||
break;
|
||||
}
|
||||
udelay(1);
|
||||
}
|
||||
if (max_retries <= 0)
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL0, "wait: INT not set\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* This function issues the specified command to the NAND device and
|
||||
* waits for completion.
|
||||
*
|
||||
* @param cmd command for NAND Flash
|
||||
*/
|
||||
static void send_cmd(u16 cmd)
|
||||
{
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL3, "send_cmd(0x%x)\n", cmd);
|
||||
|
||||
NFC_FLASH_CMD = (u16) cmd;
|
||||
NFC_CONFIG2 = NFC_CMD;
|
||||
|
||||
/* Wait for operation to complete */
|
||||
wait_op_done(TROP_US_DELAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function sends an address (or partial address) to the
|
||||
* NAND device. The address is used to select the source/destination for
|
||||
* a NAND command.
|
||||
*
|
||||
* @param addr address to be written to NFC.
|
||||
* @param islast 1 if this is the last address cycle for command
|
||||
*/
|
||||
static void send_addr(u16 addr)
|
||||
{
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL3, "send_addr(0x%x %d)\n", addr);
|
||||
|
||||
NFC_FLASH_ADDR = addr;
|
||||
NFC_CONFIG2 = NFC_ADDR;
|
||||
|
||||
/* Wait for operation to complete */
|
||||
wait_op_done(TROP_US_DELAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function requests the NANDFC to initate the transfer
|
||||
* of data currently in the NANDFC RAM buffer to the NAND device.
|
||||
*
|
||||
* @param buf_id Specify Internal RAM Buffer number (0-3)
|
||||
* @param oob set to 1 if only the spare area is transferred
|
||||
*/
|
||||
static void send_prog_page(u8 buf_id)
|
||||
{
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL3, "send_prog_page (%d)\n", nandinfo.oob);
|
||||
|
||||
/* NANDFC buffer 0 is used for page read/write */
|
||||
|
||||
NFC_BUF_ADDR = buf_id;
|
||||
|
||||
/* Configure spare or page+spare access */
|
||||
if (!nandinfo.largepage) {
|
||||
if (nandinfo.oob)
|
||||
NFC_CONFIG1 |= NFC_SP_EN;
|
||||
else
|
||||
NFC_CONFIG1 &= ~NFC_SP_EN;
|
||||
}
|
||||
NFC_CONFIG2 = NFC_INPUT;
|
||||
|
||||
/* Wait for operation to complete */
|
||||
wait_op_done(TROP_US_DELAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will correct the single bit ECC error
|
||||
*
|
||||
* @param buf_id Specify Internal RAM Buffer number (0-3)
|
||||
* @param eccpos Ecc byte and bit position
|
||||
* @param oob set to 1 if only spare area needs correction
|
||||
*/
|
||||
static void mxc_nd_correct_error(u8 buf_id, u16 eccpos, int oob)
|
||||
{
|
||||
u16 col;
|
||||
u8 pos;
|
||||
u16 *buf;
|
||||
|
||||
/* Get col & bit position of error
|
||||
these macros works for both 8 & 16 bits */
|
||||
col = COLPOS(eccpos); /* Get half-word position */
|
||||
pos = BITPOS(eccpos); /* Get bit position */
|
||||
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL3,
|
||||
"mxc_nd_correct_error (col=%d pos=%d)\n", col, pos);
|
||||
|
||||
/* Set the pointer for main / spare area */
|
||||
if (!oob)
|
||||
buf = (u16 *)(MAIN_AREA0 + col + (256 * buf_id));
|
||||
else
|
||||
buf = (u16 *)(SPARE_AREA0 + col + (8 * buf_id));
|
||||
|
||||
/* Fix the data */
|
||||
*buf ^= 1 << pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will maintains state of single bit Error
|
||||
* in Main & spare area
|
||||
*
|
||||
* @param buf_id Specify Internal RAM Buffer number (0-3)
|
||||
* @param spare set to 1 if only spare area needs correction
|
||||
*/
|
||||
static void mxc_nd_correct_ecc(u8 buf_id, int spare)
|
||||
{
|
||||
u16 value, ecc_status;
|
||||
|
||||
/* Read the ECC result */
|
||||
ecc_status = NFC_ECC_STATUS_RESULT;
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL3,
|
||||
"mxc_nd_correct_ecc (Ecc status=%x)\n", ecc_status);
|
||||
|
||||
if (((ecc_status & 0xC) == MAIN_SINGLEBIT_ERROR)
|
||||
|| ((ecc_status & 0x3) == SPARE_SINGLEBIT_ERROR)) {
|
||||
if (ecc_disabled) {
|
||||
if ((ecc_status & 0xC) == MAIN_SINGLEBIT_ERROR) {
|
||||
value = NFC_RSLTMAIN_AREA;
|
||||
/* Correct single bit error in Mainarea
|
||||
NFC will not correct the error in
|
||||
current page */
|
||||
mxc_nd_correct_error(buf_id, value, 0);
|
||||
}
|
||||
if ((ecc_status & 0x3) == SPARE_SINGLEBIT_ERROR) {
|
||||
value = NFC_RSLTSPARE_AREA;
|
||||
/* Correct single bit error in Mainarea
|
||||
NFC will not correct the error in
|
||||
current page */
|
||||
mxc_nd_correct_error(buf_id, value, 1);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Disable ECC */
|
||||
NFC_CONFIG1 &= ~NFC_ECC_EN;
|
||||
ecc_disabled = 1;
|
||||
}
|
||||
} else if (ecc_status == 0) {
|
||||
if (ecc_disabled) {
|
||||
/* Enable ECC */
|
||||
NFC_CONFIG1 |= NFC_ECC_EN;
|
||||
ecc_disabled = 0;
|
||||
}
|
||||
} /* else 2-bit Error. Do nothing */
|
||||
}
|
||||
|
||||
/**
|
||||
* This function requests the NANDFC to initated the transfer
|
||||
* of data from the NAND device into in the NANDFC ram buffer.
|
||||
*
|
||||
* @param buf_id Specify Internal RAM Buffer number (0-3)
|
||||
* @param oob set 1 if only the spare area is
|
||||
* transferred
|
||||
*/
|
||||
static void send_read_page(u8 buf_id)
|
||||
{
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", nandinfo.oob);
|
||||
|
||||
/* NANDFC buffer 0 is used for page read/write */
|
||||
NFC_BUF_ADDR = buf_id;
|
||||
|
||||
/* Configure spare or page+spare access */
|
||||
if (!nandinfo.largepage) {
|
||||
if (nandinfo.oob)
|
||||
NFC_CONFIG1 |= NFC_SP_EN;
|
||||
else
|
||||
NFC_CONFIG1 &= ~NFC_SP_EN;
|
||||
}
|
||||
|
||||
NFC_CONFIG2 = NFC_OUTPUT;
|
||||
|
||||
/* Wait for operation to complete */
|
||||
wait_op_done(TROP_US_DELAY);
|
||||
|
||||
/* If there are single bit errors in
|
||||
two consecutive page reads then
|
||||
the error is not corrected by the
|
||||
NFC for the second page.
|
||||
Correct single bit error in driver */
|
||||
|
||||
mxc_nd_correct_ecc(buf_id, nandinfo.oob);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function requests the NANDFC to perform a read of the
|
||||
* NAND device ID.
|
||||
*/
|
||||
static void send_read_id(void)
|
||||
{
|
||||
/* NANDFC buffer 0 is used for device ID output */
|
||||
NFC_BUF_ADDR = 0x0;
|
||||
|
||||
/* Read ID into main buffer */
|
||||
NFC_CONFIG1 &= ~NFC_SP_EN;
|
||||
NFC_CONFIG2 = NFC_ID;
|
||||
|
||||
/* Wait for operation to complete */
|
||||
wait_op_done(TROP_US_DELAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function requests the NANDFC to perform a read of the
|
||||
* NAND device status and returns the current status.
|
||||
*
|
||||
* @return device status
|
||||
*/
|
||||
static u16 get_dev_status(void)
|
||||
{
|
||||
volatile u16 *mainbuf = MAIN_AREA1;
|
||||
u32 store;
|
||||
u16 ret;
|
||||
/* Issue status request to NAND device */
|
||||
|
||||
/* store the main area1 first word, later do recovery */
|
||||
store = *((u32 *) mainbuf);
|
||||
/*
|
||||
* NANDFC buffer 1 is used for device status to prevent
|
||||
* corruption of read/write buffer on status requests.
|
||||
*/
|
||||
NFC_BUF_ADDR = 1;
|
||||
|
||||
/* Read status into main buffer */
|
||||
NFC_CONFIG1 &= ~NFC_SP_EN;
|
||||
NFC_CONFIG2 = NFC_STATUS;
|
||||
|
||||
/* Wait for operation to complete */
|
||||
wait_op_done(TROP_US_DELAY);
|
||||
|
||||
/* Status is placed in first word of main buffer */
|
||||
/* get status, then recovery area 1 data */
|
||||
ret = mainbuf[0];
|
||||
*((u32 *) mainbuf) = store;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
|
||||
{
|
||||
/*
|
||||
* If HW ECC is enabled, we turn it on during init. There is
|
||||
* no need to enable again here.
|
||||
*/
|
||||
}
|
||||
|
||||
static int mxc_nand_correct_data(struct mtd_info *mtd, unsigned char *dat,
|
||||
unsigned char *read_ecc, unsigned char *calc_ecc)
|
||||
{
|
||||
/*
|
||||
* 1-Bit errors are automatically corrected in HW. No need for
|
||||
* additional correction. 2-Bit errors cannot be corrected by
|
||||
* HW ECC, so we need to return failure
|
||||
*/
|
||||
u16 ecc_status = NFC_ECC_STATUS_RESULT;
|
||||
|
||||
if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL0,
|
||||
"MXC_NAND: HWECC uncorrectable 2-bit ECC error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *dat,
|
||||
unsigned char *ecc_code)
|
||||
{
|
||||
/*
|
||||
* Just return success. HW ECC does not read/write the NFC spare
|
||||
* buffer. Only the FLASH spare area contains the calcuated ECC.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function reads byte from the NAND Flash
|
||||
*
|
||||
* @param mtd MTD structure for the NAND Flash
|
||||
*
|
||||
* @return data read from the NAND Flash
|
||||
*/
|
||||
static unsigned char mxc_nand_read_byte(struct mtd_info *mtd)
|
||||
{
|
||||
unsigned char ret_val = 0;
|
||||
u16 col, rd_word;
|
||||
volatile u16 *mainbuf = MAIN_AREA0;
|
||||
volatile u16 *sparebuf = SPARE_AREA0;
|
||||
|
||||
/* Check for status request */
|
||||
if (nandinfo.read_status)
|
||||
return get_dev_status() & 0xFF;
|
||||
|
||||
/* Get column for 16-bit access */
|
||||
col = nandinfo.col >> 1;
|
||||
|
||||
/* If we are accessing the spare region */
|
||||
if (nandinfo.oob)
|
||||
rd_word = sparebuf[col];
|
||||
else
|
||||
rd_word = mainbuf[col];
|
||||
|
||||
/* Pick upper/lower byte of word from RAM buffer */
|
||||
if (nandinfo.col & 0x1)
|
||||
ret_val = (rd_word >> 8) & 0xFF;
|
||||
else
|
||||
ret_val = rd_word & 0xFF;
|
||||
|
||||
/* Update saved column address */
|
||||
nandinfo.col++;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function reads word from the NAND Flash
|
||||
*
|
||||
* @param mtd MTD structure for the NAND Flash
|
||||
*
|
||||
* @return data read from the NAND Flash
|
||||
*/
|
||||
static u16 mxc_nand_read_word(struct mtd_info *mtd)
|
||||
{
|
||||
u16 col;
|
||||
u16 rd_word, ret_val;
|
||||
volatile u16 *p;
|
||||
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL3, "mxc_nand_read_word(col = %d)\n", nandinfo.col);
|
||||
|
||||
col = nandinfo.col;
|
||||
/* Adjust saved column address */
|
||||
if (col < mtd->writesize && nandinfo.oob)
|
||||
col += mtd->writesize;
|
||||
|
||||
if (col < mtd->writesize)
|
||||
p = (MAIN_AREA0) + (col >> 1);
|
||||
else
|
||||
p = (SPARE_AREA0) + ((col - mtd->writesize) >> 1);
|
||||
|
||||
if (col & 1) {
|
||||
rd_word = *p;
|
||||
ret_val = (rd_word >> 8) & 0xff;
|
||||
rd_word = *(p + 1);
|
||||
ret_val |= (rd_word << 8) & 0xff00;
|
||||
|
||||
} else
|
||||
ret_val = *p;
|
||||
|
||||
/* Update saved column address */
|
||||
nandinfo.col = col + 2;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function writes data of length \b len to buffer \b buf. The data
|
||||
* to be written on NAND Flash is first copied to RAMbuffer. After the
|
||||
* Data Input Operation by the NFC, the data is written to NAND Flash.
|
||||
*
|
||||
* @param mtd MTD structure for the NAND Flash
|
||||
* @param buf data to be written to NAND Flash
|
||||
* @param len number of bytes to be written
|
||||
*/
|
||||
static void mxc_nand_write_buf(struct mtd_info *mtd,
|
||||
const unsigned char *buf, int len)
|
||||
{
|
||||
int n;
|
||||
int col;
|
||||
int i = 0;
|
||||
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL3,
|
||||
"mxc_nand_write_buf(col = %d, len = %d)\n", nandinfo.col, len);
|
||||
|
||||
col = nandinfo.col;
|
||||
|
||||
/* Adjust saved column address */
|
||||
if (col < mtd->writesize && nandinfo.oob)
|
||||
col += mtd->writesize;
|
||||
|
||||
n = mtd->writesize + mtd->oobsize - col;
|
||||
if (len > mtd->writesize + mtd->oobsize - col)
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL1, "Error: too much data.\n");
|
||||
|
||||
n = min(len, n);
|
||||
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL3,
|
||||
"%s:%d: col = %d, n = %d\n", __FUNCTION__, __LINE__, col, n);
|
||||
|
||||
while (n) {
|
||||
volatile u32 *p;
|
||||
if (col < mtd->writesize)
|
||||
p = (volatile u32 *)((ulong) (MAIN_AREA0) + (col & ~3));
|
||||
else
|
||||
p = (volatile u32 *)((ulong) (SPARE_AREA0) -
|
||||
mtd->writesize + (col & ~3));
|
||||
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL3, "%s:%d: p = %p\n",
|
||||
__FUNCTION__, __LINE__, p);
|
||||
|
||||
if (((col | (int)&buf[i]) & 3) || n < 16) {
|
||||
u32 data = 0;
|
||||
|
||||
if (col & 3 || n < 4)
|
||||
data = *p;
|
||||
|
||||
switch (col & 3) {
|
||||
case 0:
|
||||
if (n) {
|
||||
data = (data & 0xffffff00) |
|
||||
(buf[i++] << 0);
|
||||
n--;
|
||||
col++;
|
||||
}
|
||||
case 1:
|
||||
if (n) {
|
||||
data = (data & 0xffff00ff) |
|
||||
(buf[i++] << 8);
|
||||
n--;
|
||||
col++;
|
||||
}
|
||||
case 2:
|
||||
if (n) {
|
||||
data = (data & 0xff00ffff) |
|
||||
(buf[i++] << 16);
|
||||
n--;
|
||||
col++;
|
||||
}
|
||||
case 3:
|
||||
if (n) {
|
||||
data = (data & 0x00ffffff) |
|
||||
(buf[i++] << 24);
|
||||
n--;
|
||||
col++;
|
||||
}
|
||||
}
|
||||
|
||||
*p = data;
|
||||
} else {
|
||||
int m = mtd->writesize - col;
|
||||
|
||||
if (col >= mtd->writesize)
|
||||
m += mtd->oobsize;
|
||||
|
||||
m = min(n, m) & ~3;
|
||||
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL3,
|
||||
"%s:%d: n = %d, m = %d, i = %d, col = %d\n",
|
||||
__FUNCTION__, __LINE__, n, m, i, col);
|
||||
|
||||
memcpy_32((void *)(p), &buf[i], m);
|
||||
col += m;
|
||||
i += m;
|
||||
n -= m;
|
||||
}
|
||||
}
|
||||
/* Update saved column address */
|
||||
nandinfo.col = col;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function id is used to read the data buffer from the NAND Flash. To
|
||||
* read the data from NAND Flash first the data output cycle is initiated by
|
||||
* the NFC, which copies the data to RAMbuffer. This data of length \b len is
|
||||
* then copied to buffer \b buf.
|
||||
*
|
||||
* @param mtd MTD structure for the NAND Flash
|
||||
* @param buf data to be read from NAND Flash
|
||||
* @param len number of bytes to be read
|
||||
*/
|
||||
static void mxc_nand_read_buf(struct mtd_info *mtd, unsigned char *buf, int len)
|
||||
{
|
||||
int n;
|
||||
int col;
|
||||
int i = 0;
|
||||
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL3,
|
||||
"mxc_nand_read_buf(col = %d, len = %d)\n", nandinfo.col, len);
|
||||
|
||||
col = nandinfo.col;
|
||||
/**
|
||||
* Adjust saved column address
|
||||
* for nand_read_oob will pass col within oobsize
|
||||
*/
|
||||
if (col < mtd->writesize && nandinfo.oob)
|
||||
col += mtd->writesize;
|
||||
|
||||
n = mtd->writesize + mtd->oobsize - col;
|
||||
n = min(len, n);
|
||||
|
||||
while (n) {
|
||||
volatile u32 *p;
|
||||
|
||||
if (col < mtd->writesize)
|
||||
p = (volatile u32 *)((ulong) (MAIN_AREA0) + (col & ~3));
|
||||
else
|
||||
p = (volatile u32 *)((ulong) (SPARE_AREA0) -
|
||||
mtd->writesize + (col & ~3));
|
||||
|
||||
if (((col | (int)&buf[i]) & 3) || n < 16) {
|
||||
u32 data;
|
||||
|
||||
data = *p;
|
||||
switch (col & 3) {
|
||||
case 0:
|
||||
if (n) {
|
||||
buf[i++] = (u8) (data);
|
||||
n--;
|
||||
col++;
|
||||
}
|
||||
case 1:
|
||||
if (n) {
|
||||
buf[i++] = (u8) (data >> 8);
|
||||
n--;
|
||||
col++;
|
||||
}
|
||||
case 2:
|
||||
if (n) {
|
||||
buf[i++] = (u8) (data >> 16);
|
||||
n--;
|
||||
col++;
|
||||
}
|
||||
case 3:
|
||||
if (n) {
|
||||
buf[i++] = (u8) (data >> 24);
|
||||
n--;
|
||||
col++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int m = mtd->writesize - col;
|
||||
|
||||
if (col >= mtd->writesize)
|
||||
m += mtd->oobsize;
|
||||
|
||||
m = min(n, m) & ~3;
|
||||
memcpy_32(&buf[i], (void *)(p), m);
|
||||
col += m;
|
||||
i += m;
|
||||
n -= m;
|
||||
}
|
||||
}
|
||||
/* Update saved column address */
|
||||
nandinfo.col = col;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used by the upper layer to verify the data in NAND Flash
|
||||
* with the data in the \b buf.
|
||||
*
|
||||
* @param mtd MTD structure for the NAND Flash
|
||||
* @param buf data to be verified
|
||||
* @param len length of the data to be verified
|
||||
*
|
||||
* @return -EFAULT if error else 0
|
||||
*/
|
||||
static int
|
||||
mxc_nand_verify_buf(struct mtd_info *mtd, const unsigned char *buf, int len)
|
||||
{
|
||||
return -1; /* Was -EFAULT */
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used by upper layer for select and deselect of the NAND
|
||||
* chip.
|
||||
*
|
||||
* @param mtd MTD structure for the NAND Flash
|
||||
* @param chip val indicating select or deselect
|
||||
*/
|
||||
static void mxc_nand_select_chip(struct mtd_info *mtd, int chip)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used by the upper layer to write command to NAND Flash
|
||||
* for different operations to be carried out on NAND Flash
|
||||
*
|
||||
* @param mtd MTD structure for the NAND Flash
|
||||
* @param command command for NAND Flash
|
||||
* @param column column offset for the page read
|
||||
* @param page_addr page to be read from NAND Flash
|
||||
*/
|
||||
static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
|
||||
int column, int page_addr)
|
||||
{
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL3,
|
||||
"mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n",
|
||||
command, column, page_addr);
|
||||
|
||||
/* Reset command state information */
|
||||
nandinfo.read_status = 0;
|
||||
nandinfo.oob = 0;
|
||||
|
||||
/* Command pre-processing step */
|
||||
switch (command) {
|
||||
|
||||
case NAND_CMD_STATUS:
|
||||
nandinfo.col = 0;
|
||||
nandinfo.read_status = 1;
|
||||
break;
|
||||
|
||||
case NAND_CMD_READ0:
|
||||
nandinfo.col = column;
|
||||
break;
|
||||
|
||||
case NAND_CMD_READOOB:
|
||||
nandinfo.col = column;
|
||||
nandinfo.oob = 1;
|
||||
if (nandinfo.largepage)
|
||||
command = NAND_CMD_READ0;
|
||||
break;
|
||||
|
||||
case NAND_CMD_SEQIN:
|
||||
if (column >= mtd->writesize) {
|
||||
/* write oob routine caller */
|
||||
if (nandinfo.largepage) {
|
||||
/*
|
||||
* FIXME: before send SEQIN command for
|
||||
* write OOB, we must read one page out.
|
||||
* For 2K nand has no READ1 command to set
|
||||
* current HW pointer to spare area, we must
|
||||
* write the whole page including OOB together.
|
||||
*/
|
||||
/* call itself to read a page */
|
||||
mxc_nand_command(mtd, NAND_CMD_READ0, 0,
|
||||
page_addr);
|
||||
}
|
||||
nandinfo.col = column - mtd->writesize;
|
||||
nandinfo.oob = 1;
|
||||
/* Set program pointer to spare region */
|
||||
if (!nandinfo.largepage)
|
||||
send_cmd(NAND_CMD_READOOB);
|
||||
} else {
|
||||
nandinfo.oob = 0;
|
||||
nandinfo.col = column;
|
||||
/* Set program pointer to page start */
|
||||
if (!nandinfo.largepage)
|
||||
send_cmd(NAND_CMD_READ0);
|
||||
}
|
||||
break;
|
||||
|
||||
case NAND_CMD_PAGEPROG:
|
||||
if (ecc_disabled) {
|
||||
/* Enable Ecc for page writes */
|
||||
NFC_CONFIG1 |= NFC_ECC_EN;
|
||||
}
|
||||
send_prog_page(0);
|
||||
|
||||
if (nandinfo.largepage) {
|
||||
/* data in 4 areas datas */
|
||||
send_prog_page(1);
|
||||
send_prog_page(2);
|
||||
send_prog_page(3);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NAND_CMD_ERASE1:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write out the command to the device.
|
||||
*/
|
||||
send_cmd(command);
|
||||
|
||||
/*
|
||||
* Write out column address, if necessary
|
||||
*/
|
||||
if (column != -1) {
|
||||
/*
|
||||
* MXC NANDFC can only perform full page+spare or
|
||||
* spare-only read/write. When the upper layers
|
||||
* layers perform a read/write buf operation,
|
||||
* we will used the saved column adress to index into
|
||||
* the full page.
|
||||
*/
|
||||
send_addr(0);
|
||||
if (nandinfo.largepage)
|
||||
/* another col addr cycle for 2k page */
|
||||
send_addr(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write out page address, if necessary
|
||||
*/
|
||||
if (page_addr != -1) {
|
||||
/* paddr_0 - p_addr_7 */
|
||||
send_addr((page_addr & 0xff));
|
||||
|
||||
if (nandinfo.largepage) {
|
||||
/* One more address cycle for higher
|
||||
* density devices */
|
||||
|
||||
if (mtd->size >= 0x10000000) {
|
||||
/* paddr_8 - paddr_15 */
|
||||
send_addr((page_addr >> 8) & 0xff);
|
||||
send_addr((page_addr >> 16) & 0xff);
|
||||
} else
|
||||
/* paddr_8 - paddr_15 */
|
||||
send_addr((page_addr >> 8) & 0xff);
|
||||
} else {
|
||||
/* One more address cycle for higher
|
||||
* density devices */
|
||||
|
||||
if (mtd->size >= 0x4000000) {
|
||||
/* paddr_8 - paddr_15 */
|
||||
send_addr((page_addr >> 8) & 0xff);
|
||||
send_addr((page_addr >> 16) & 0xff);
|
||||
} else
|
||||
/* paddr_8 - paddr_15 */
|
||||
send_addr((page_addr >> 8) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Command post-processing step
|
||||
*/
|
||||
switch (command) {
|
||||
|
||||
case NAND_CMD_RESET:
|
||||
break;
|
||||
|
||||
case NAND_CMD_READOOB:
|
||||
case NAND_CMD_READ0:
|
||||
if (nandinfo.largepage) {
|
||||
/* send read confirm command */
|
||||
send_cmd(NAND_CMD_READSTART);
|
||||
/* read for each AREA */
|
||||
send_read_page(0);
|
||||
send_read_page(1);
|
||||
send_read_page(2);
|
||||
send_read_page(3);
|
||||
} else
|
||||
send_read_page(0);
|
||||
break;
|
||||
|
||||
case NAND_CMD_READID:
|
||||
send_read_id();
|
||||
nandinfo.col = column;
|
||||
break;
|
||||
|
||||
case NAND_CMD_PAGEPROG:
|
||||
if (ecc_disabled) {
|
||||
/* Disable Ecc after page writes */
|
||||
NFC_CONFIG1 &= ~NFC_ECC_EN;
|
||||
}
|
||||
break;
|
||||
|
||||
case NAND_CMD_ERASE2:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int mxc_nand_scan_bbt(struct mtd_info *mtd)
|
||||
{
|
||||
struct nand_chip *this = mtd->priv;
|
||||
|
||||
/* Config before scanning */
|
||||
/* Do not rely on NFMS_BIT, set/clear NFMS bit based
|
||||
* on mtd->writesize */
|
||||
if (mtd->writesize == 2048)
|
||||
NFMS |= 1 << NFMS_BIT;
|
||||
else if ((NFMS >> NFMS_BIT) & 0x1)
|
||||
NFMS &= ~(1 << NFMS_BIT);
|
||||
|
||||
/* use flash based bbt */
|
||||
this->bbt_td = &bbt_main_descr;
|
||||
this->bbt_md = &bbt_mirror_descr;
|
||||
|
||||
/* update flash based bbt */
|
||||
this->options |= NAND_USE_FLASH_BBT;
|
||||
|
||||
if (!this->badblock_pattern) {
|
||||
if (nandinfo.largepage)
|
||||
this->badblock_pattern = &smallpage_memorybased;
|
||||
else
|
||||
this->badblock_pattern = (mtd->writesize > 512) ?
|
||||
&largepage_memorybased : &smallpage_memorybased;
|
||||
}
|
||||
/* Build bad block table */
|
||||
return nand_scan_bbt(mtd, this->badblock_pattern);
|
||||
}
|
||||
|
||||
int board_nand_init(struct nand_chip *nand)
|
||||
{
|
||||
nand->chip_delay = 0;
|
||||
|
||||
nand->cmdfunc = mxc_nand_command;
|
||||
nand->select_chip = mxc_nand_select_chip;
|
||||
nand->read_byte = mxc_nand_read_byte;
|
||||
nand->read_word = mxc_nand_read_word;
|
||||
nand->write_buf = mxc_nand_write_buf;
|
||||
nand->read_buf = mxc_nand_read_buf;
|
||||
nand->verify_buf = mxc_nand_verify_buf;
|
||||
nand->scan_bbt = mxc_nand_scan_bbt;
|
||||
nand->ecc.calculate = mxc_nand_calculate_ecc;
|
||||
nand->ecc.correct = mxc_nand_correct_data;
|
||||
nand->ecc.hwctl = mxc_nand_enable_hwecc;
|
||||
nand->ecc.mode = NAND_ECC_HW;
|
||||
nand->ecc.bytes = 3;
|
||||
nand->ecc.size = 512;
|
||||
|
||||
/* Reset NAND */
|
||||
NFC_CONFIG1 |= NFC_INT_MSK | NFC_RST | NFC_ECC_EN;
|
||||
|
||||
/* Unlock the internal RAM buffer */
|
||||
NFC_CONFIG = 0x2;
|
||||
|
||||
/* Block to be unlocked */
|
||||
NFC_UNLOCKSTART_BLKADDR = 0x0;
|
||||
NFC_UNLOCKEND_BLKADDR = 0x4000;
|
||||
|
||||
/* Unlock Block Command for given address range */
|
||||
NFC_WRPROT = 0x4;
|
||||
|
||||
/* Only 8 bit bus support for now */
|
||||
nand->options |= 0;
|
||||
|
||||
if ((NFMS >> NFMS_BIT) & 1) {
|
||||
nandinfo.largepage = 1;
|
||||
nand->ecc.layout = &nand_hw_eccoob_2k;
|
||||
} else {
|
||||
nandinfo.largepage = 0;
|
||||
nand->ecc.layout = &nand_hw_eccoob_8;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
1277
drivers/mtd/nand/mxc_nand.c
Normal file
1277
drivers/mtd/nand/mxc_nand.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -45,7 +45,7 @@ static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,
|
||||
|
||||
nand->IO_ADDR_R = nand->IO_ADDR_W = (void __iomem *)base_addr;
|
||||
if (board_nand_init(nand) == 0) {
|
||||
if (nand_scan(mtd, 1) == 0) {
|
||||
if (nand_scan(mtd, NAND_MAX_CHIPS) == 0) {
|
||||
if (!mtd->name)
|
||||
mtd->name = (char *)default_nand_name;
|
||||
} else
|
||||
|
||||
@ -848,8 +848,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this)
|
||||
|
||||
while (1) {
|
||||
if (get_timer(0) > timeo) {
|
||||
printf("Timeout!");
|
||||
return 0x01;
|
||||
/*printf("Timeout!");*/
|
||||
/*return 0x01;*/
|
||||
}
|
||||
|
||||
if (this->dev_ready) {
|
||||
@ -2510,7 +2510,8 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
|
||||
mtd->writesize = 1024 << (extid & 0x3);
|
||||
extid >>= 2;
|
||||
/* Calc oobsize */
|
||||
mtd->oobsize = (8 << (extid & 0x01)) * (mtd->writesize >> 9);
|
||||
mtd->oobsize = (*maf_id == 0x2c && dev_id == 0xd5) ?
|
||||
218 : (8 << (extid & 0x01)) * (mtd->writesize >> 9);
|
||||
extid >>= 2;
|
||||
/* Calc blocksize. Blocksize is multiples of 64KiB */
|
||||
mtd->erasesize = (64 * 1024) << (extid & 0x03);
|
||||
@ -2843,10 +2844,9 @@ int nand_scan_tail(struct mtd_info *mtd)
|
||||
mtd->ecclayout = chip->ecc.layout;
|
||||
|
||||
/* Check, if we should skip the bad block table scan */
|
||||
if (chip->options & NAND_SKIP_BBTSCAN)
|
||||
chip->options |= NAND_BBT_SCANNED;
|
||||
chip->options |= NAND_BBT_SCANNED;
|
||||
|
||||
return 0;
|
||||
return chip->scan_bbt(mtd);
|
||||
}
|
||||
|
||||
/* module_text_address() isn't exported, and it's mostly a pointless
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user