Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Sami Nurmenniemi
u-boot-stm32
Commits
87098936
Commit
87098936
authored
Oct 03, 2013
by
Pavel Boldin
Browse files
RT #89962: Added support for EA LPC4357 OEM board
parent
f7b4a226
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
87098936
...
...
@@ -3271,6 +3271,9 @@ k70-som_config : unconfig
lpc4350-eval_config
:
unconfig
@
$(MKCONFIG)
$
(
@:_config
=)
arm arm_cortexm3 lpc4350-eval hitex lpc18xx
ea-lpc4357_config
:
unconfig
@
$(MKCONFIG)
$
(
@:_config
=)
arm arm_cortexm3 ea-lpc4357 nxp lpc18xx
lpc1850-eval_config
:
unconfig
@
$(MKCONFIG)
$
(
@:_config
=)
arm arm_cortexm3 lpc1850-eval hitex lpc18xx
...
...
board/hitex/lpc4350-eval/board.c
View file @
87098936
...
...
@@ -36,6 +36,7 @@
#include
<asm/arch/lpc18xx_scu.h>
#include
<asm/arch/lpc18xx_creg.h>
#include
<asm/arch/lpc18xx_ccu.h>
#include
<asm/arch/lpc18xx_emc.h>
/*
* IS42S16400F SDRAM: 16-bit, 4 banks, 12 row bits, 8 column bits.
...
...
@@ -168,80 +169,6 @@
/* CAS latency */
#define LPC_EMC_DYRASCAS_CAS_BITS 8
/*
* EMC per-chip registers for DRAM.
*
* This structure must be 0x20 bytes in size
* (for `struct lpc_emc_regs` to be correct.)
*/
struct
lpc_emc_dy_regs
{
u32
cfg
;
/* Dynamic Memory Configuration register */
u32
rascas
;
/* Dynamic Memory RAS & CAS Delay registers */
u32
rsv0
[
6
];
};
/*
* EMC controls for Static Memory CS. Each block occupies 0x20 bytes.
*/
struct
lpc_emc_st_regs
{
u32
cfg
;
/* Static Memory Configuration register */
u32
we
;
/* CS to WE delay register */
u32
oe
;
/* CS to OE delay register */
u32
rd
;
/* CS to Read delay register */
u32
page
;
/* async page mode access delay */
u32
wr
;
/* CS to Write delay register */
u32
ta
;
/* number of turnaround cycles */
u32
rsv0
[
1
];
};
/*
* EMC (External Memory Controller) register map
*/
struct
lpc_emc_regs
{
/* 0x000 */
u32
emcctrl
;
/* EMC Control register */
u32
emcsts
;
/* EMC Status register */
u32
emccfg
;
/* EMC Configuration register */
u32
rsv0
[
5
];
/* 0x020 */
u32
dy_ctrl
;
/* Dynamic Memory Control register */
u32
dy_rfsh
;
/* Dynamic Memory Refresh Timer register */
u32
dy_rdcfg
;
/* Dynamic Memory Read Configuration register */
u32
rsv1
;
/* 0x030 */
u32
dy_trp
;
/* Dynamic Memory Precharge Command Period register */
u32
dy_tras
;
/* Dynamic Memory Active to Precharge Command
Period register */
u32
dy_srex
;
/* Dynamic Memory Self-refresh Exit Time register */
u32
dy_apr
;
/* Dynamic Memory Last Data Out to Active
Time register */
u32
dy_dal
;
/* Dynamic Memory Data-in to Active Command
Time register */
u32
dy_wr
;
/* Dynamic Memory Write Recovery Time register */
u32
dy_rc
;
/* Dynamic Memory Active to Active Command
Period register */
u32
dy_rfc
;
/* Dynamic Memory Auto-refresh Period register */
u32
dy_xsr
;
/* Dynamic Memory Exit Self-refresh register */
u32
dy_rrd
;
/* Dynamic Memory Active Bank A to
Active Bank B Time register */
u32
dy_mrd
;
/* Dynamic Memory Load Mode register to
Active Command Time */
/* 0x05C */
u32
rsv2
[
41
];
/* 0x100 */
struct
lpc_emc_dy_regs
dy
[
4
];
/* 4 DRAM chips are possible */
u32
rsv3
[
32
];
/* 0x200 */
struct
lpc_emc_st_regs
st
[
4
];
/* 4 static memory devices */
};
#define LPC18XX_EMC_BASE 0x40005000
#define LPC_EMC ((volatile struct lpc_emc_regs *) \
LPC18XX_EMC_BASE)
DECLARE_GLOBAL_DATA_PTR
;
/*
...
...
board/nxp/ea-lpc4357/Makefile
0 → 100644
View file @
87098936
#
# (C) Copyright 2011
#
# Alexander Potashev, Emcraft Systems, aspotashev@emcraft.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
$(TOPDIR)/config.mk
LIB
=
$(obj)
lib
$(BOARD)
.a
COBJS
:=
board.o
SRCS
:=
$(COBJS:.o=.c)
OBJS
:=
$(
addprefix
$(obj)
,
$(COBJS)
)
$(LIB)
:
$(obj).depend $(OBJS)
$(AR)
$(ARFLAGS)
$@
$(OBJS)
clean
:
rm
-f
$(OBJS)
distclean
:
clean
rm
-f
$(LIB)
core
*
.bak
$(obj)
.depend
#########################################################################
# defines $(obj).depend target
include
$(SRCTREE)/rules.mk
sinclude
$(obj).depend
board/nxp/ea-lpc4357/board.c
0 → 100644
View file @
87098936
This diff is collapsed.
Click to expand it.
cpu/arm_cortexm3/config.mk
View file @
87098936
...
...
@@ -28,6 +28,10 @@ PLATFORM_CPPFLAGS += -DCONFIG_MEM_RAM_LEN=$(CONFIG_MEM_RAM_LEN)
PLATFORM_CPPFLAGS
+=
-DCONFIG_MEM_RAM_BUF_LEN
=
$(CONFIG_MEM_RAM_BUF_LEN)
PLATFORM_CPPFLAGS
+=
-DCONFIG_MEM_MALLOC_LEN
=
$(CONFIG_MEM_MALLOC_LEN)
PLATFORM_CPPFLAGS
+=
-DCONFIG_MEM_STACK_LEN
=
$(CONFIG_MEM_STACK_LEN)
ifdef
CONFIG_MEM_RAMCODE_BASE
PLATFORM_CPPFLAGS
+=
-DCONFIG_MEM_RAMCODE_BASE
=
$(CONFIG_MEM_RAMCODE_BASE)
PLATFORM_CPPFLAGS
+=
-DCONFIG_MEM_RAMCODE_LEN
=
$(CONFIG_MEM_RAMCODE_LEN)
endif
PLATFORM_CPPFLAGS
+=
-I
$(TOPDIR)
/cpu/
$(CPU)
...
...
cpu/arm_cortexm3/envm.h
View file @
87098936
...
...
@@ -27,6 +27,10 @@
*/
void
envm_init
(
void
);
#if !defined(CONFIG_ARMCORTEXM3_RAMCODE) && defined(CONFIG_LPC43XX_ENVM)
# error "LPC43XX ENVM requires RAMCODE"
#endif
/*
* Write a data buffer to eNVM.
* Note that we need for this function to reside in RAM since it
...
...
cpu/arm_cortexm3/lpc18xx/Makefile
View file @
87098936
...
...
@@ -29,7 +29,12 @@ include $(TOPDIR)/config.mk
LIB
=
$(obj)
lib
$(SOC)
.a
COBJS
:=
clock.o cpu.o envm.o wdt.o
COBJS
:=
clock.o cpu.o wdt.o
ifeq
($(CONFIG_LPC43XX_ENVM),y)
COBJS
+=
envm-lpc43xx.o
else
COBJS
+=
envm-lpc18xx.o
endif
ifeq
($(CONFIG_SPIFI),y)
COBJS
+=
spifi.o
endif
...
...
cpu/arm_cortexm3/lpc18xx/clock.c
View file @
87098936
...
...
@@ -23,6 +23,7 @@
#include
<asm/errno.h>
#include
<asm/arch/lpc18xx_creg.h>
#include
<asm/arch/lpc18xx.h>
#include
"clock.h"
/*
...
...
@@ -193,12 +194,6 @@ struct lpc18xx_rgu_regs {
*/
static
u32
clock_val
[
CLOCK_END
];
/*
* Set LPC18XX_PLL1_CLK_OUT to the output rate of PLL1
*/
#define LPC18XX_PLL1_CLK_OUT \
(CONFIG_LPC18XX_EXTOSC_RATE * CONFIG_LPC18XX_PLL1_M)
/*
* Compile time sanity checks for defined board clock setup
*/
...
...
@@ -211,7 +206,7 @@ static u32 clock_val[CLOCK_END];
* of 156 MHz to 320 MHz, so that the PLL1 Direct Mode is applicable.
* Our clock configuration code (`clock_setup()`) support only this mode.
*/
#if LPC18XX_PLL1_CLK_OUT < 1
56
000000
#if LPC18XX_PLL1_CLK_OUT < 1
44
000000
#error Requested PLL1 output frequency is too low
#endif
#if LPC18XX_PLL1_CLK_OUT > 320000000
...
...
@@ -337,6 +332,7 @@ void eth_clock_setup(void)
int
timeout
;
int
rv
;
#ifndef CONFIG_LPC18XX_ENET_USE_PHY_RMII
/*
* This clock configuration is valid only for MII
*/
...
...
@@ -344,13 +340,18 @@ void eth_clock_setup(void)
LPC18XX_CGU_CLKSEL_ENET_RX
|
LPC18XX_CGU_AUTOBLOCK_MSK
;
LPC18XX_CGU
->
phy_tx_clk
=
LPC18XX_CGU_CLKSEL_ENET_TX
|
LPC18XX_CGU_AUTOBLOCK_MSK
;
#endif
/* CONFIG_LPC18XX_ENET_USE_PHY_RMII */
/*
* Choose the MII Ethernet mode
*/
LPC18XX_CREG
->
creg6
=
(
LPC18XX_CREG
->
creg6
&
~
LPC18XX_CREG_CREG6_ETHMODE_MSK
)
|
#ifndef CONFIG_LPC18XX_ENET_USE_PHY_RMII
LPC18XX_CREG_CREG6_ETHMODE_MII
;
#else
LPC18XX_CREG_CREG6_ETHMODE_RMII
;
#endif
/*
* Reset the Ethernet module of the MCU
...
...
cpu/arm_cortexm3/lpc18xx/envm.c
→
cpu/arm_cortexm3/lpc18xx/envm
-lpc18xx
.c
View file @
87098936
File moved
cpu/arm_cortexm3/lpc18xx/envm-lpc43xx.c
0 → 100644
View file @
87098936
/*
* (C) Copyright 2011-2013
*
* Alexander Potashev, Emcraft Systems, aspotashev@emcraft.com
* Pavel Boldin, Emcraft Systems, paboldin@emcraft.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include
<common.h>
#include
<errno.h>
#include
"envm.h"
/*
* IAP library for editing eNVM
*/
/* IAP function pointer */
#define IAP_LOCATION_PTR 0x10400100
typedef
void
(
*
lpc43xn_iap
)
(
u32
*
,
u32
*
);
/* IAP commands */
#define IAP_CMD_INIT 49
#define IAP_CMD_PREP_SECTORS 50
#define IAP_CMD_RAM_TO_FLASH 51
#define IAP_CMD_ERASE_SECTORS 52
#define IAP_CMD_BLANK_CHECK_SECTORS 53
#define IAP_CMD_READ_PART_ID 54
/* IAP statuses */
#define IAP_STATUS_SUCCESS 0
/*
* Block size used for the "Copy RAM to Flash" operation
*
* Can be 256, 512, 1024 or 4096
*/
#define IAP_BLOCK_SIZE 512
#define IAP_BLOCK_MASK (IAP_BLOCK_SIZE - 1)
static
u32
iap_clkrate
;
/* CPU clock in KHz */
/*
* List of block addresses and sizes
*
* IMPORTANT: We force this data into the `.data` section, because otherwise
* it will be in eNVM and will be overwritten on self-upgrade.
*/
static
lpc43xn_iap
lpc43xn_iap_entry
__attribute__
((
section
(
".data"
)));
struct
lpc43xn_flash_layout
{
int
sectors
;
int
size
;
};
static
struct
lpc43xn_flash_layout
flash_layout
[]
__attribute__
((
section
(
".data"
)))
=
{
{
8
,
8192
},
{
7
,
65536
}
};
static
u32
iap_commands
[
6
];
static
u32
iap_results
[
5
];
/*
* A temporary buffer in SRAM (section `.bss`) used for the "Copy RAM to Flash"
* operation. We need this buffer, because direct transfer from the external RAM
* does not work.
*
* This buffer should be aligned on a 4 byte boundary.
*/
static
u8
iap_sram_buf
[
IAP_BLOCK_SIZE
]
__attribute__
((
aligned
(
4
)));
/*
* Prepare sectors for erase or write
*/
int
__attribute__
((
section
(
".ramcode"
)))
__attribute__
((
long_call
))
lpc43xn_iap_prepare_sectors
(
u32
start
,
u32
end
,
u32
bank
)
{
iap_commands
[
0
]
=
IAP_CMD_PREP_SECTORS
;
iap_commands
[
1
]
=
start
;
iap_commands
[
2
]
=
end
;
iap_commands
[
3
]
=
bank
;
lpc43xn_iap_entry
(
iap_commands
,
iap_results
);
return
iap_results
[
0
];
}
/*
* Copy RAM to FLASH
*/
int
__attribute__
((
section
(
".ramcode"
)))
__attribute__
((
long_call
))
lpc43xn_iap_ram_to_flash
(
u32
dst
,
u32
src
,
u32
bytes
)
{
iap_commands
[
0
]
=
IAP_CMD_RAM_TO_FLASH
;
iap_commands
[
1
]
=
dst
;
iap_commands
[
2
]
=
src
;
iap_commands
[
3
]
=
bytes
;
iap_commands
[
4
]
=
iap_clkrate
;
lpc43xn_iap_entry
(
iap_commands
,
iap_results
);
return
iap_results
[
0
];
}
/*
* Erase sectors
*/
int
__attribute__
((
section
(
".ramcode"
)))
__attribute__
((
long_call
))
lpc43xn_iap_erase_sectors
(
u32
start
,
u32
end
,
u32
bank
)
{
iap_commands
[
0
]
=
IAP_CMD_ERASE_SECTORS
;
iap_commands
[
1
]
=
start
;
iap_commands
[
2
]
=
end
;
iap_commands
[
3
]
=
iap_clkrate
;
iap_commands
[
4
]
=
bank
;
lpc43xn_iap_entry
(
iap_commands
,
iap_results
);
return
iap_results
[
0
];
}
/*
* Blank check sectors
*/
int
__attribute__
((
section
(
".ramcode"
)))
__attribute__
((
long_call
))
lpc43xn_iap_blank_check_sectors
(
u32
start
,
u32
end
,
u32
bank
,
u32
*
bad_addr
,
u32
*
bad_data
)
{
iap_commands
[
0
]
=
IAP_CMD_BLANK_CHECK_SECTORS
;
iap_commands
[
1
]
=
start
;
iap_commands
[
2
]
=
end
;
iap_commands
[
3
]
=
bank
;
lpc43xn_iap_entry
(
iap_commands
,
iap_results
);
*
bad_addr
=
iap_results
[
1
];
*
bad_data
=
iap_results
[
2
];
return
iap_results
[
0
];
}
/*
* Initialize IAP library - call this first
*
* This function should not be in .ramcode, because it will be called only once
* before self-upgrade.
*/
void
lpc43xn_iap_init
(
void
)
{
lpc43xn_iap_entry
=
(
lpc43xn_iap
)
*
(
u32
*
)
IAP_LOCATION_PTR
;
iap_commands
[
0
]
=
IAP_CMD_INIT
;
lpc43xn_iap_entry
(
iap_commands
,
iap_results
);
if
(
iap_results
[
0
]
!=
IAP_STATUS_SUCCESS
)
{
printf
(
"%s: failed %d
\n
"
,
__func__
,
iap_results
[
0
]);
return
;
}
}
/*
* Initialize internal Flash interface
*
* This function should not be in .ramcode, because it will be called only once
* before self-upgrade.
*/
void
envm_init
(
void
)
{
lpc43xn_iap_init
();
}
/*
* `addr` is the offset from the beginning of eNVM
*/
static
u32
__attribute__
((
section
(
".ramcode"
)))
__attribute__
((
long_call
))
find_sector
(
u32
addr
,
u32
bank
)
{
u32
i
,
j
,
current
=
CONFIG_MEM_NVM_BASE
,
sector
=
0
;
#ifdef CONFIG_MEM_NVM2_BASE
current
=
bank
?
CONFIG_MEM_NVM2_BASE
:
CONFIG_MEM_NVM_BASE
;
#endif
for
(
i
=
0
;
flash_layout
[
i
].
sectors
;
i
++
)
{
for
(
j
=
0
;
j
<
flash_layout
[
i
].
sectors
;
j
++
)
{
if
(
addr
<
current
+
flash_layout
[
i
].
size
)
{
return
sector
;
}
sector
++
;
current
+=
flash_layout
[
i
].
size
;
}
}
return
-
1
;
}
/*
* Erase FLASH sectors
*/
int
__attribute__
((
section
(
".ramcode"
)))
__attribute__
((
long_call
))
lpc43xn_flash_erase
(
u32
offset
,
u32
size
,
u32
bank
)
{
int
rv
;
u32
badaddr
,
baddata
;
u32
first
,
last
;
/*
* Convert (offset, size) to (first, last)
*/
first
=
find_sector
(
offset
,
bank
);
last
=
find_sector
(
offset
+
size
-
1
,
bank
);
if
(
first
<
0
||
last
<
first
||
last
>=
#ifdef CONFIG_MEM_NVM2_BASE
bank
?
CONFIG_MEM_NVM2_SECTORS
:
#endif
CONFIG_MEM_NVM_SECTORS
)
{
rv
=
-
EINVAL
;
goto
out
;
}
if
(
lpc43xn_iap_prepare_sectors
(
first
,
last
,
bank
)
!=
IAP_STATUS_SUCCESS
)
{
rv
=
-
EIO
;
goto
out
;
}
if
(
lpc43xn_iap_erase_sectors
(
first
,
last
,
bank
)
!=
IAP_STATUS_SUCCESS
)
{
rv
=
-
EIO
;
goto
out
;
}
if
(
lpc43xn_iap_blank_check_sectors
(
first
,
last
,
bank
,
&
badaddr
,
&
baddata
)
!=
IAP_STATUS_SUCCESS
)
{
rv
=
-
EIO
;
goto
out
;
}
rv
=
0
;
out:
return
rv
;
}
/*
* Copy memory buffer to FLASH
*/
int
__attribute__
((
section
(
".ramcode"
)))
__attribute__
((
long_call
))
lpc43xn_flash_program
(
u32
dest_addr
,
u8
*
src
,
u32
size
)
{
int
rv
;
u32
offset
;
/* Offset of the current block being written */
u32
i
;
u32
sect
,
bank
=
0
;
#ifdef CONFIG_MEM_NVM2_BASE
bank
=
CONFIG_MEM_NVM2_BASE
<=
dest_addr
;
#endif
u8
*
dest
=
(
u8
*
)
dest_addr
;
/*
* Write size must be on a block boundary
*/
if
(
size
&
IAP_BLOCK_MASK
)
{
rv
=
-
EINVAL
;
goto
out
;
}
/*
* Write address must be on a 256 byte boundary
* (even if IAP_BLOCK_SIZE is not 256)
*/
if
(
dest_addr
&
0xFF
)
{
rv
=
-
EINVAL
;
goto
out
;
}
/*
* Write range should not exceed the end of FLASH
*/
if
(
size
>
#ifdef CONFIG_MEM_NVM2_LEN
bank
?
CONFIG_MEM_NVM2_LEN
:
#endif
CONFIG_MEM_NVM_LEN
)
{
rv
=
-
EINVAL
;
goto
out
;
}
/*
* Check that the destination area is erased
*/
for
(
i
=
0
;
i
<
size
;
i
++
)
{
if
(
dest
[
i
]
!=
0xFF
)
{
/* FLASH is not blank */
rv
=
-
EEXIST
;
goto
out
;
}
}
/*
* Write data in blocks of size IAP_BLOCK_SIZE
*/
for
(
offset
=
0
;
offset
<
size
;
offset
+=
IAP_BLOCK_SIZE
)
{
sect
=
find_sector
(
dest_addr
+
offset
,
bank
);
if
(
lpc43xn_iap_prepare_sectors
(
sect
,
sect
,
bank
)
!=
IAP_STATUS_SUCCESS
)
{
rv
=
-
EACCES
;
goto
out
;
}
/*
* Copy block into the second SRAM region
* ("Peripheral RAM"). Cannot use `memcpy()` here, because it
* resides in eNVM, not in `.ramcode` section.
*/
for
(
i
=
0
;
i
<
IAP_BLOCK_SIZE
;
i
++
)
iap_sram_buf
[
i
]
=
src
[
offset
+
i
];
/*
* Copy block from RAM to FLASH
*/
if
(
lpc43xn_iap_ram_to_flash
(
dest_addr
+
offset
,
(
u32
)
iap_sram_buf
,
IAP_BLOCK_SIZE
)
!=
IAP_STATUS_SUCCESS
)
{
rv
=
-
EACCES
;
goto
out
;
}
}
/*
* Verify
*/
for
(
i
=
0
;
i
<
size
;
i
++
)
{
if
(
dest
[
i
]
!=
src
[
i
])
{
rv
=
-
EAGAIN
;
goto
out
;
}
}
rv
=
0
;
out:
return
rv
;
}