Commit 69790f01 authored by Pavel Boldin's avatar Pavel Boldin

RT #89962 EA-LPC4357: SPIFI support, eNVM fix

parent 87098936
......@@ -309,9 +309,13 @@ $(obj)u-boot.srec: $(obj)u-boot
$(OBJCOPY) -O srec $< $@
ifeq ($(CONFIG_SYS_LPC18XX)$(CONFIG_SPIFI),yy)
SPIFILIB_DEP = cpu/arm_cortexm3/lpc18xx/spifilib/spifilib.bin
ifeq ($(CONFIG_SPIFILIB_IN_ENVM),y)
SPIFILIB_DEP = cpu/arm_cortexm3/lpc18xx/spifilib/spifilib-envm.bin
else
SPIFILIB_DEP = cpu/arm_cortexm3/lpc18xx/spifilib/spifilib-dram.bin
endif
$(SPIFILIB_DEP): depend
$(MAKE) -C cpu/arm_cortexm3/lpc18xx/spifilib -f spifilib.mk
$(MAKE) -C cpu/arm_cortexm3/lpc18xx/spifilib $(notdir $(SPIFILIB_DEP)) -f spifilib.mk
endif
$(obj)u-boot.bin: $(obj)u-boot $(SPIFILIB_DEP)
......@@ -325,7 +329,7 @@ ifeq ($(CONFIG_LPC18XX_BOOTHEADER),y)
mv $(obj)u-boot-bootheader.bin $(obj)u-boot.bin
endif
ifeq ($(CONFIG_SYS_LPC18XX)$(CONFIG_SPIFI),yy)
dd if=cpu/arm_cortexm3/lpc18xx/spifilib/spifilib.bin of=u-boot.bin seek=112 bs=1024
dd if=$(SPIFILIB_DEP) of=u-boot.bin seek=112 bs=1024
endif
$(obj)u-boot.upgrade: $(obj)u-boot.bin
......
......@@ -49,7 +49,7 @@
/* Active to read/write delay (RAS latency) */
#define SDRAM_RAS 3 /* From EA example */
/* CAS latency (CL) */
#define SDRAM_CAS 3 /* CL = 2 */
#define SDRAM_CAS 3 /* CL = 3 */
/* Command delayed strategy, using EMCCLKDELAY */
#define SDRAM_RDCFG_RD 1
/* Precharge command period (tRP) */
......@@ -82,7 +82,7 @@
* Indicates the multiple of 16 CCLKs between SDRAM refresh cycles.
*/
/* (64ms / 4096 row) */
#define SDRAM_REFRESH (NS2CLK(64000000 / 4096) / 16)
#define SDRAM_REFRESH ((NS2CLK(64000000 / 4096) / 16) - 1)
/* Only for initialization */
#define SDRAM_REFRESH_FAST 2
......@@ -124,9 +124,9 @@
/*
* See IS42S32800D mode register (IS42S32800D datasheet, page 23),
* and EA example code.
* CAS3, Burst Length = 8.
* CAS3, Burst Length = 4.
*/
#define SDRAM_MODEREG_BL 3 /* Burst Length code */
#define SDRAM_MODEREG_BL 2 /* Burst Length code */
#define SDRAM_MODEREG_CAS 3 /* CAS Latency */
#define SDRAM_MODEREG_VALUE \
......@@ -137,7 +137,6 @@
* SDRAM chip-specific options
*/
/*
* FIXME
* Offset of the 12 least-significant bits of mode register (A0..A11)
* in addresses on the AHB bus.
*
......@@ -175,7 +174,7 @@
DECLARE_GLOBAL_DATA_PTR;
/*
* Pin configuration table for Hitex LPC4350 Eval.
* Pin configuration table for EA LPC4357 OEM.
*
* This table does not list all MCU pins that will be configured. See also
* the code in `iomux_init()`.
......@@ -389,6 +388,22 @@ static const struct lpc18xx_pin_config ea_lpc4357_iomux[] = {
/* P1.5 = CS0# - NOR */
{{0x1, 5}, LPC18XX_IOMUX_EMC_CONFIG(3)},
#endif /* CONFIG_SYS_FLASH_CS */
#if defined(CONFIG_SPIFI)
/* P3.3 = SPIFI_SCK */
{{0x3, 3}, LPC18XX_IOMUX_EMC_CONFIG(3)},
/* P3.4 = SPIFI_SIO3 */
{{0x3, 4}, LPC18XX_IOMUX_SPIFI_CONFIG(3)},
/* P3.5 = SPIFI_SIO2 */
{{0x3, 5}, LPC18XX_IOMUX_SPIFI_CONFIG(3)},
/* P3.6 = SPIFI_MISO */
{{0x3, 6}, LPC18XX_IOMUX_SPIFI_CONFIG(3)},
/* P3.6 = SPIFI_MOSI */
{{0x3, 7}, LPC18XX_IOMUX_SPIFI_CONFIG(3)},
/* P3.6 = SPIFI_CS */
{{0x3, 8}, LPC18XX_IOMUX_CONFIG(3, 0, 1, 0, 0, 0)},
#endif
};
/*
......@@ -578,8 +593,6 @@ void __attribute__((section(".lpc18xx_image_top_text")))
*/
int board_init(void)
{
volatile struct lpc_emc_st_regs *st;
/*
* Set SDRAM clock output delay to ~3.5ns (0x7777),
* the SDRAM chip does not work otherwise.
......@@ -611,10 +624,6 @@ int board_init(void)
st->ta = CONFIG_SYS_FLASH_TA;
#endif
#if defined(CONFIG_LPC_SPI)
spi_init();
#endif
return 0;
}
......@@ -644,8 +653,6 @@ int misc_init_r(void)
}
#endif /* CONFIG_MISC_INIT_R */
#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})
/*
* Setup external RAM.
*/
......@@ -681,10 +688,10 @@ int dram_init(void)
dy->rascas =
(SDRAM_RAS << LPC_EMC_DYRASCAS_RAS_BITS) |
(SDRAM_CAS << LPC_EMC_DYRASCAS_CAS_BITS);
LPC_EMC->dy_rdcfg =
(SDRAM_RDCFG_RD << LPC_EMC_DYRDCFG_RD_BITS);
LPC_EMC->dy_trp = SDRAM_T_RP;
LPC_EMC->dy_tras = SDRAM_T_RAS;
LPC_EMC->dy_srex = SDRAM_T_SREX;
......@@ -696,7 +703,7 @@ int dram_init(void)
LPC_EMC->dy_xsr = SDRAM_T_XSR;
LPC_EMC->dy_rrd = SDRAM_T_RRD;
LPC_EMC->dy_mrd = SDRAM_T_MRD;
mdelay(100);
udelay(100);
/*
* Issue SDRAM NOP (no operation) command
......@@ -704,7 +711,7 @@ int dram_init(void)
LPC_EMC->dy_ctrl =
LPC_EMC_DYCTRL_CE_MSK | LPC_EMC_DYCTRL_CS_MSK |
(LPC_EMC_DYCTRL_I_NOP << LPC_EMC_DYCTRL_I_BITS);
mdelay(200);
udelay(200);
/*
* Pre-charge all with fast refresh
......@@ -713,7 +720,7 @@ int dram_init(void)
LPC_EMC_DYCTRL_CE_MSK | LPC_EMC_DYCTRL_CS_MSK |
(LPC_EMC_DYCTRL_I_PALL << LPC_EMC_DYCTRL_I_BITS);
LPC_EMC->dy_rfsh = SDRAM_REFRESH_FAST;
mdelay(200);
udelay(200);
/*
* Set refresh period
......
......@@ -63,9 +63,26 @@ int saveenv(void)
*/
int env_init(void)
{
#ifndef CONFIG_SPIFILIB_IN_ENVM
/* SPIFI lib is not accessible before DRAM initialization */
gd->env_addr = (ulong)&default_environment[0];
gd->env_valid = 0;
return 0;
#else
ulong crc, len, new;
unsigned off;
uchar buf[64];
if (spifi_initialize()) {
/*
* SPIFI initalization failed
*/
gd->env_addr = (ulong)&default_environment[0];
gd->env_valid = 0;
goto out;
}
if (gd->env_valid == 0){
/* read old CRC */
memcpy((char *)&crc, (char *)CONFIG_ENV_ADDR + offsetof(env_t, crc),
......@@ -89,5 +106,7 @@ int env_init(void)
}
}
out:
return (0);
#endif /* CONFIG_SPIFILIB_IN_ENVM */
}
......@@ -57,8 +57,8 @@ int
/*
* Copy the buffer to the destination.
*/
if (envm_write((uint) dst, (void *) src, (uint) size) != size) {
ret = -1;
ret = envm_write((uint) dst, (void *) src, (uint) size);
if (ret != size) {
goto Done;
}
......@@ -119,8 +119,9 @@ int do_cptf(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
/*
* Copy the buffer to the destination.
*/
if (envm_write_and_reset(dst, src, size, do_reset)) {
printf("%s: nvm_write_and_reset failed\n", (char *) argv[0]);
if ((ret = envm_write_and_reset(dst, src, size, do_reset)) <= 0) {
printf("%s: envm_write_and_reset failed: %d\n",
(char *) argv[0], ret);
goto Done;
}
......
......@@ -24,6 +24,16 @@
#include <errno.h>
#include "envm.h"
/*
* Convinience macro for selecting value for bank.
*/
#ifdef CONFIG_MEM_NVM2_BASE
# define CONFIG_NVM_VALUE(bank, VALUE) (bank ? CONFIG_MEM_NVM2_##VALUE : CONFIG_MEM_NVM_##VALUE)
#else
# define CONFIG_NVM_VALUE(bank, VALUE) (CONFIG_MEM_NVM_##VALUE)
#endif
/*
* IAP library for editing eNVM
*/
......@@ -197,11 +207,7 @@ void envm_init(void)
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
u32 i, j, current = CONFIG_NVM_VALUE(bank, BASE), sector = 0;
for (i = 0; flash_layout[i].sectors; i++)
{
......@@ -236,11 +242,7 @@ lpc43xn_flash_erase(u32 offset, u32 size, u32 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) {
last >= CONFIG_NVM_VALUE(bank, SECTORS)) {
rv = -EINVAL;
goto out;
}
......@@ -306,11 +308,7 @@ lpc43xn_flash_program(u32 dest_addr, u8 *src, u32 size)
/*
* 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) {
if (size > CONFIG_NVM_VALUE(bank, LEN)) {
rv = -EINVAL;
goto out;
}
......@@ -382,7 +380,7 @@ u32 __attribute__((section(".ramcode")))
__attribute__((long_call))
envm_write(u32 offset, void *buf, u32 size)
{
u32 rv = 0, bank = 0;
int rv = 0, bank = 0;
/*
* Clock in is CPU in KHz
......@@ -410,10 +408,13 @@ envm_write(u32 offset, void *buf, u32 size)
bank = CONFIG_MEM_NVM2_BASE <= offset;
#endif
if (lpc43xn_flash_erase(offset, size, bank) < 0 ||
lpc43xn_flash_program(offset, buf,
(size + IAP_BLOCK_MASK) &
~IAP_BLOCK_MASK) < 0)
rv = lpc43xn_flash_erase(offset, size, bank);
if (rv < 0)
goto out;
rv = lpc43xn_flash_program(offset, buf,
(size + IAP_BLOCK_MASK) & ~IAP_BLOCK_MASK);
if (rv < 0)
goto out;
rv = size;
......
......@@ -2,6 +2,7 @@
* (C) Copyright 2013
*
* Dmitry Konyshev, Emcraft Systems, probables@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
......@@ -30,9 +31,19 @@ int spifi_initialize(void)
int ret;
if (spifilib_flash_hdr->signature == SPIFILIB_SIG) {
/*
* Already initalized, skip
*/
if (spifilib_ram_hdr != NULL)
return 0;
#ifndef CONFIG_SPIFILIB_IN_ENVM
spifilib_ram_hdr = spifilib_flash_hdr->link_addr;
memcpy(spifilib_flash_hdr->link_addr, spifilib_flash_hdr,
spifilib_flash_hdr->lib_size);
#else
spifilib_ram_hdr = spifilib_flash_hdr;
#endif
if ((ret = spifilib_ram_hdr->init_func(&spifi_obj, 10, S_MODE3, 25))) {
spifilib_ram_hdr = NULL;
printf("SPIFI lib init failed with code %i\n", ret);
......
/*
* (C) Copyright 2013
* Dmitry Konyshev, Emcraft Systems, probables@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
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
"elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
MEMORY
{
RAM (rw): ORIGIN = 0x1A01C000, LENGTH = 0x4000
}
SECTIONS
{
.text :
{
*(.rodata.spifilib.header)
*(.text)
*(.rodata*)
*(.constdata*)
} >RAM
/DISCARD/ :
{
*(*)
}
}
......@@ -23,11 +23,16 @@
#define __SPIFILIB_H
#include "spifi_rom_api.h"
#include <config.h>
#define SPIFILIB_SIG 0x591F121B
#define SPIFILIB_SIZE (16*1024)
#define SPIFI_BASE_ADDR 0x14000000
#ifdef CONFIG_SPIFILIB_IN_ENVM
# define SPIFI_BASE_ADDR CONFIG_MEM_NVM_BASE
#else
# define SPIFI_BASE_ADDR 0x14000000
#endif
typedef int32_t (*spifi_init_t)(SPIFIobj *obj, uint32_t csHigh, uint32_t options, uint32_t mhz);
typedef int32_t (*spifi_program_t)(SPIFIobj *obj, char *source, SPIFIopers *opers);
......
......@@ -17,14 +17,24 @@
# MA 02111-1307 USA
#
spifilib.bin: spifilib
# This should be done with .incbin and Position-Independent-Code
SPIFILIB_VERSION ?= M3
spifilib-envm.bin: spifilib-envm
$(OBJCOPY) -O binary $< $@
spifilib: spifilib.o spifi_drv_M3.lib spifilib.lds
$(LD) $(LDLAGS) -Map spifilib.map -Tspifilib.lds -nostdlib -o $@ spifilib.o spifi_drv_M3.lib
spifilib-dram.bin: spifilib-dram
$(OBJCOPY) -O binary $< $@
spifilib-envm: spifilib.o spifi_drv_$(SPIFILIB_VERSION).lib spifilib-envm.lds
$(LD) $(LDLAGS) -Map spifilib.map -Tspifilib-envm.lds -nostdlib -o $@ spifilib.o spifi_drv_$(SPIFILIB_VERSION).lib
spifilib-dram: spifilib.o spifi_drv_$(SPIFILIB_VERSION).lib spifilib-dram.lds
$(LD) $(LDLAGS) -Map spifilib.map -Tspifilib-dram.lds -nostdlib -o $@ spifilib.o spifi_drv_$(SPIFILIB_VERSION).lib
spifilib.o: spifilib.h spifilib.c
$(CC) $(CFLAGS) -fshort-wchar -fshort-enums -c $+
clean:
$(RM) spifilib.o spifilib spifilib.bin
$(RM) spifilib.o spifilib-envm spifilib-dram spifilib-envm.bin spifilib-dram.bin
......@@ -115,7 +115,7 @@ struct lpc_emc_regs {
//#define NS2CLK(time) (((LPC18XX_EMC_CLK_OUT / 1000000) * (time)) / 1000)
static inline uint32_t NS2CLK(uint32_t time){
uint32_t tmp = LPC18XX_EMC_CLK_OUT/1000000;
return (tmp * time) / 1000;
return (tmp * time + 999) / 1000;
}
......
......@@ -64,6 +64,11 @@
*/
#define LPC18XX_IOMUX_EMC_CONFIG(func) \
(LPC18XX_IOMUX_CONFIG(func, 0, 1, 1, 1, 1))
/*
* Pin settings for slow EMC pins (SPIFI)
*/
#define LPC18XX_IOMUX_SPIFI_CONFIG(func) \
(LPC18XX_IOMUX_CONFIG(func, 0, 1, 0, 1, 1))
/*
* Pin settings for GPIO input pins
*/
......
......@@ -172,10 +172,12 @@
*/
#define CONFIG_LPC18XX_EMC_HALFCPU
/*
#define CONFIG_ENV_IS_NOWHERE
#define CONFIG_ENV_SIZE (4 * 1024)
#define CONFIG_ENV_ADDR 0
*/
/* Uncomment the following line to disable Flash support */
#define CONFIG_SYS_NO_FLASH
......@@ -183,7 +185,7 @@
/*
* Configuration of the external Flash memory
*/
#define CONFIG_SYS_FLASH_CS 0
#define CONFIG_SYS_FLASH_CS 1
#define CONFIG_SYS_FLASH_CFG 0x81 /* 16 bit, Byte Lane enabled */
#define CONFIG_SYS_FLASH_WE (1 - 1) /* Minimum is enough */
#define CONFIG_SYS_FLASH_OE 0 /* Minimum is enough */
......@@ -213,17 +215,18 @@
/* Uncomment the following line to enable the SPIFI interface */
/*#define CONFIG_SPIFI*/
#define CONFIG_SPIFI
#ifdef CONFIG_SPIFI
#define CONFIG_SPIFI_BASE 0x14000000
#define CONFIG_SPIFI_SIZE (16*1024*1024)
#define CONFIG_SPIFI_SIZE (2*1024*1024)
#define CONFIG_SPIFILIB_IN_ENVM /* Place SPIFI lib into ENVM */
#ifndef CONFIG_ENV_IS_IN_FLASH
#if !defined(CONFIG_ENV_IS_IN_FLASH) && !defined(CONFIG_ENV_IS_NOWHERE)
#define CONFIG_ENV_IS_IN_SPIFI
#define CONFIG_ENV_SIZE (4 * 1024)
#define CONFIG_ENV_ADDR \
(CONFIG_SPIFI_BASE + 128 * 1024)
#define CONFIG_ENV_ADDR CONFIG_SPIFI_BASE
#define CONFIG_ENV_OVERWRITE 1
#endif
#endif
......@@ -369,7 +372,7 @@
#define CONFIG_EXTRA_ENV_SETTINGS \
"loadaddr=0x28000000\0" \
"addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off\0" \
"flashaddr=1C040000\0" \
"flashaddr=0x14001000\0" \
"flashboot=run addip;bootm ${flashaddr}\0" \
"ethaddr=C0:B1:3C:88:78:93\0" \
"ipaddr=172.17.4.215\0" \
......
......@@ -32,4 +32,8 @@ extern int spifi_initialize(void);
extern int spifi_write(ulong off, const void *buf, ulong size);
extern void spifi_cancel_mem_mode(void);
#if defined(CONFIG_ENV_IS_IN_SPIFI) && !defined(CONFIG_SPIFILIB_IN_ENVM)
# error "Keeping environment in SPIFI requires it to reside in eNVM or IRAM, not in DRAM"
#endif
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment