Commit f271a6db authored by Alexander Potashev's avatar Alexander Potashev
Browse files

RT76276. Add support for STMicroelectronics STM3240G-EVAL board

* Clone the board-specific files from those used for the STM3220G-EVAL board.
* Change STM3220G-EVAL to STM3240G-EVAL where appropriate.
* cpu/arm_cortexm3/stm32/clock.c: Add support for clock rates up to 168 MHz.
* Ethernet driver: Implement us/ms delays not tied to CPU clock rate.
* Ethernet driver: Add `stm_phy_wait_busy()` to reduce code duplication.
* Raise system clock rate from 120 MHz to 168 MHz.
* Update PSRAM timings.
* Disable the PSRAM Synchronous Burst Mode.
parent 79bfcd78
#
# (C) Copyright 2011
#
# Yuri Tikhonov, Emcraft Systems, yur@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
/*
* (C) Copyright 2011, 2012
*
* Yuri Tikhonov, Emcraft Systems, yur@emcraft.com
* Alexander Potashev, Emcraft Systems, aspotashev@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
*/
/*
* Board specific code for the STMicroelectronic STM3220G-EVAL board
*/
#include <common.h>
#include <netdev.h>
#include <ili932x.h>
#include <asm/arch/stm32.h>
#include <asm/arch/stm32f2_gpio.h>
#include <asm/arch/fsmc.h>
#if (CONFIG_NR_DRAM_BANKS > 0)
/*
* Check if RAM configured
*/
# if !defined(CONFIG_SYS_RAM_CS) || !defined(CONFIG_SYS_FSMC_PSRAM_BCR) || \
!defined(CONFIG_SYS_FSMC_PSRAM_BTR)
# error "Incorrect PSRAM FSMC configuration."
# endif
#endif /* CONFIG_NR_DRAM_BANKS */
DECLARE_GLOBAL_DATA_PTR;
/*
* Early hardware init.
*/
int board_init(void)
{
int rv;
#if !defined(CONFIG_SYS_NO_FLASH)
if ((rv = fsmc_nor_psram_init(CONFIG_SYS_FLASH_CS, CONFIG_SYS_FSMC_FLASH_BCR,
CONFIG_SYS_FSMC_FLASH_BTR,
CONFIG_SYS_FSMC_FLASH_BWTR)))
return rv;
#endif
#if defined(CONFIG_LCD)
/*
* Configure FSMC for accessing the LCD controller
*/
if ((rv = fsmc_nor_psram_init(CONFIG_LCD_CS, CONFIG_LCD_FSMC_BCR,
CONFIG_LCD_FSMC_BTR, CONFIG_LCD_FSMC_BWTR)))
return rv;
gd->fb_base = CONFIG_FB_ADDR;
#endif
return 0;
}
/*
* Dump pertinent info to the console.
*/
int checkboard(void)
{
printf("Board: STM3240G-EVAL board + STM-MEM add-on,%s\n",
CONFIG_SYS_BOARD_REV_STR);
return 0;
}
/*
* Setup external RAM.
*/
int dram_init(void)
{
static struct stm32f2_gpio_dsc ctrl_gpio = {STM32F2_GPIO_PORT_I,
STM32F2_GPIO_PIN_9};
int rv = 0;
rv = fsmc_nor_psram_init(CONFIG_SYS_RAM_CS,
CONFIG_SYS_FSMC_PSRAM_BCR,
CONFIG_SYS_FSMC_PSRAM_BTR,
#ifdef CONFIG_SYS_FSMC_PSRAM_BWTR
CONFIG_SYS_FSMC_PSRAM_BWTR
#else
(u32)-1
#endif
);
if (rv != 0)
goto out;
rv = stm32f2_gpio_config(&ctrl_gpio, STM32F2_GPIO_ROLE_GPOUT);
if (rv != 0)
goto out;
# if defined(CONFIG_SYS_RAM_BURST)
/*
* FIXME: all this hardcoded stuff.
*/
/* Step.2 */
stm32f2_gpout_set(&ctrl_gpio, 1);
/* Step.3 */
*(volatile u16 *)(CONFIG_SYS_RAM_BASE + 0x0010223E) = 0;
/* Step.4-5 */
stm32f2_gpout_set(&ctrl_gpio, 0);
/* Step.6 */
fsmc_nor_psram_init(CONFIG_SYS_RAM_CS, 0x00083115,
0x0010FFFF, -1);
/* Step.7 */
rv = *(volatile u16 *)(CONFIG_SYS_RAM_BASE + 0x000000);
/* Step.8 */
fsmc_nor_psram_init(CONFIG_SYS_RAM_CS, 0x00005059,
0x10000702, 0x10000602);
/* Step.9 */
stm32f2_gpout_set(&ctrl_gpio, 1);
/* Step.10 */
*(volatile u16 *)(CONFIG_SYS_RAM_BASE + 0x0110223E) = 0;
/* Step.11 */
stm32f2_gpout_set(&ctrl_gpio, 0);
/* Step.12 */
fsmc_nor_psram_init(CONFIG_SYS_RAM_CS, 0x00083115,
0x0010FFFF, -1);
/* Step.13 */
rv = *(volatile u16 *)(CONFIG_SYS_RAM_BASE + 0x01000000);
# else
/*
* Switch PSRAM in the Asyncronous Read/Write Mode
*/
stm32f2_gpout_set(&ctrl_gpio, 0);
# endif /* CONFIG_SYS_RAM_BURST */
/*
* Fill in global info with description of SRAM configuration
*/
gd->bd->bi_dram[0].start = CONFIG_SYS_RAM_BASE;
gd->bd->bi_dram[0].size = CONFIG_SYS_RAM_SIZE;
rv = 0;
out:
return rv;
}
#ifdef CONFIG_STM32_ETH
/*
* Register ethernet driver
*/
int board_eth_init(bd_t *bis)
{
return stm32_eth_init(bis);
}
#endif
......@@ -135,6 +135,10 @@
# define STM32_FLASH_WS 2
#elif (STM32_SYS_CLK > 90000000) && (STM32_SYS_CLK <= 120000000)
# define STM32_FLASH_WS 3
#elif (STM32_SYS_CLK > 120000000) && (STM32_SYS_CLK <= 150000000)
# define STM32_FLASH_WS 4
#elif (STM32_SYS_CLK > 150000000) && (STM32_SYS_CLK <= 168000000)
# define STM32_FLASH_WS 5
#else
# error "Incorrect System clock value configuration."
# define STM32_FLASH_WS 0 /* to avoid compile-time err */
......
......@@ -73,7 +73,7 @@
#define STM32_MAC_MIIAR_CR_BIT 2 /* Clock range */
#define STM32_MAC_MIIAR_CR_MSK 0x7
#define STM32_MAC_MIIAR_CR_DIV42 0x0 /* 60-100 MHz */
#define STM32_MAC_MIIAR_CR_DIV62 0x1 /* 100-120 MHz */
#define STM32_MAC_MIIAR_CR_DIV62 0x1 /* 100-168 MHz */
#define STM32_MAC_MIIAR_CR_DIV16 0x2 /* 20-35 MHz */
#define STM32_MAC_MIIAR_CR_DIV26 0x3 /* 35-60 MHz */
......@@ -164,15 +164,14 @@
#define STM32_RCC_ENR_ETHMACRXEN (1 << 27) /* Ethernet Rx clock */
/*
* Different timeouts (in cycles)
* FIXME: replace this stuff with us/ms timeouts (when implement timer support)
* Different timeouts
*/
#define STM32_PHY_READ_TIMEOUT 0x4FFFF
#define STM32_PHY_WRITE_TIMEOUT 0x4FFFF
#define STM32_PHY_AUTONEG_TIMEOUT 0x10000
#define STM32_PHY_READ_TIMEOUT 2500 /* x 100 usec = 250 ms */
#define STM32_PHY_WRITE_TIMEOUT 2500 /* x 100 usec = 250 ms */
#define STM32_PHY_AUTONEG_TIMEOUT 100000 /* x 100 usec = 10 s */
#define STM32_MAC_TX_TIMEOUT 0xFFFFFF
#define STM32_MAC_INIT_TIMEOUT 0xFFFFFF
#define STM32_MAC_TX_TIMEOUT 1000000 /* x 1 usec = 1000 ms */
#define STM32_MAC_INIT_TIMEOUT 20000 /* x 100 usec = 2 s */
/*
* MAC, MMC, PTP, DMA register map
......@@ -487,7 +486,7 @@ static s32 stm_phy_link_setup(struct stm_eth_dev *mac)
{
static s32 link_inited;
s32 link_up, full_dup, speed, rv, i;
s32 link_up, full_dup, speed, rv, timeout;
u32 cr_val;
u16 val;
......@@ -524,15 +523,17 @@ static s32 stm_phy_link_setup(struct stm_eth_dev *mac)
/*
* Wait until auto-negotioation complete
*/
for (i = 0, val = 0; i < STM32_PHY_AUTONEG_TIMEOUT; i++) {
if (stm_phy_read(mac, PHY_BMSR, &val) != 0)
continue;
if (val & PHY_BMSR_AUTN_COMP) {
printf("completed.\n");
break;
}
timeout = STM32_PHY_AUTONEG_TIMEOUT;
while (timeout-- > 0) {
if (stm_phy_read(mac, PHY_BMSR, &val) == 0 &&
(val & PHY_BMSR_AUTN_COMP))
timeout = 0;
else
udelay(100);
}
if (!(val & PHY_BMSR_AUTN_COMP))
if (val & PHY_BMSR_AUTN_COMP)
printf("completed.\n");
else
printf("timeout.\n");
/*
......@@ -573,6 +574,29 @@ out:
return rv;
}
/*
* Helper function used in stm_phy_read() and stm_phy_write()
*/
static int stm_phy_wait_busy(int timeout)
{
int rv;
rv = -ETIMEDOUT;
while (timeout-- > 0) {
if (STM32_MAC->macmiiar & STM32_MAC_MIIAR_MB) {
udelay(100);
} else {
timeout = 0;
rv = 0;
}
}
if (rv != 0)
printf("%s: timed out\n", __func__);
return rv;
}
/*
* Write PHY
*/
......@@ -582,10 +606,7 @@ static s32 stm_phy_write(struct stm_eth_dev *mac, u16 reg, u16 val)
u32 tmp;
s32 rv;
tmp = 0;
while ((STM32_MAC->macmiiar & STM32_MAC_MIIAR_MB) &&
(tmp++ < STM32_PHY_WRITE_TIMEOUT));
if (STM32_MAC->macmiiar & STM32_MAC_MIIAR_MB) {
if (stm_phy_wait_busy(STM32_PHY_WRITE_TIMEOUT) != 0) {
/*
* MII is busy
*/
......@@ -618,10 +639,7 @@ static s32 stm_phy_write(struct stm_eth_dev *mac, u16 reg, u16 val)
STM32_MAC->macmiidr = val;
STM32_MAC->macmiiar = tmp;
tmp = 0;
while ((STM32_MAC->macmiiar & STM32_MAC_MIIAR_MB) &&
(tmp++ < STM32_PHY_WRITE_TIMEOUT));
if (STM32_MAC->macmiiar & STM32_MAC_MIIAR_MB) {
if (stm_phy_wait_busy(STM32_PHY_WRITE_TIMEOUT) != 0) {
/*
* Transaction failed: Write timeout
*/
......@@ -646,10 +664,7 @@ static s32 stm_phy_read(struct stm_eth_dev *mac, u16 reg, u16 *val)
u32 tmp;
s32 rv;
tmp = 0;
while ((STM32_MAC->macmiiar & STM32_MAC_MIIAR_MB) &&
(tmp++ < STM32_PHY_READ_TIMEOUT));
if (STM32_MAC->macmiiar & STM32_MAC_MIIAR_MB) {
if (stm_phy_wait_busy(STM32_PHY_READ_TIMEOUT) != 0) {
/*
* MII is busy
*/
......@@ -681,10 +696,7 @@ static s32 stm_phy_read(struct stm_eth_dev *mac, u16 reg, u16 *val)
*/
STM32_MAC->macmiiar = tmp;
tmp = 0;
while ((STM32_MAC->macmiiar & STM32_MAC_MIIAR_MB) &&
(tmp++ < STM32_PHY_READ_TIMEOUT));
if (STM32_MAC->macmiiar & STM32_MAC_MIIAR_MB) {
if (stm_phy_wait_busy(STM32_PHY_READ_TIMEOUT) != 0) {
/*
* Transaction failed: read timeout
*/
......@@ -817,7 +829,7 @@ out:
static s32 stm_mac_hw_init(struct stm_eth_dev *mac)
{
u32 tmp, hclk;
s32 i, rv;
s32 rv, timeout;
/*
* Init GPIOs
......@@ -840,14 +852,19 @@ static s32 stm_mac_hw_init(struct stm_eth_dev *mac)
STM32_RCC->ahb1rstr &= ~STM32_RCC_AHB1RSTR_MAC;
STM32_MAC->dmabmr |= STM32_MAC_DMABMR_SR;
i = 0;
while (STM32_MAC->dmabmr & STM32_MAC_DMABMR_SR) {
if (i++ > STM32_MAC_INIT_TIMEOUT)
break;
timeout = STM32_MAC_INIT_TIMEOUT;
rv = -EBUSY;
while (timeout-- > 0) {
if (STM32_MAC->dmabmr & STM32_MAC_DMABMR_SR) {
udelay(100);
} else {
timeout = 0;
rv = 0;
}
}
if (STM32_MAC->dmabmr & STM32_MAC_DMABMR_SR) {
if (rv != 0) {
printf("%s: failed reset MAC subsystem.\n", __func__);
rv = -EBUSY;
goto out;
}
......@@ -879,21 +896,16 @@ static s32 stm_mac_hw_init(struct stm_eth_dev *mac)
/* CSR Clock range between 60-100 MHz */
tmp = STM32_MAC_MIIAR_CR_DIV42 << STM32_MAC_MIIAR_CR_BIT;
} else {
/* CSR Clock range between 100-120 MHz */
/* CSR Clock range between 100-168 MHz */
tmp = STM32_MAC_MIIAR_CR_DIV62 << STM32_MAC_MIIAR_CR_BIT;
}
if (STM32_MAC->macmiiar & STM32_MAC_MIIAR_MB) {
i = 0;
while ((STM32_MAC->macmiiar & STM32_MAC_MIIAR_MB) &&
(i++ < STM32_PHY_READ_TIMEOUT));
if (STM32_MAC->macmiiar & STM32_MAC_MIIAR_MB) {
/*
* MII is busy
*/
rv = -EBUSY;
goto out;
}
if (stm_phy_wait_busy(STM32_PHY_READ_TIMEOUT) != 0) {
/*
* MII is busy
*/
rv = -EBUSY;
goto out;
}
STM32_MAC->macmiiar = tmp;
......@@ -1008,14 +1020,18 @@ static s32 stm_eth_send(struct eth_device *dev, volatile void *pkt, s32 len)
/*
* Wait until transmit completes
*/
for (tout = 0; tout < STM32_MAC_TX_TIMEOUT; tout++) {
tout = STM32_MAC_TX_TIMEOUT;
rv = -ETIMEDOUT;
while (tout-- > 0) {
if (mac->tx_bd.stat & STM32_DMA_TBD_DMA_OWN)
continue;
break;
udelay(1);
else {
tout = 0;
rv = 0;
}
}
if (mac->tx_bd.stat & STM32_DMA_TBD_DMA_OWN) {
if (rv != 0) {
printf("%s: timeout.\n", __func__);
rv = -ETIMEDOUT;
goto out;
}
......
/*
* (C) Copyright 2011, 2012
*
* Yuri Tikhonov, Emcraft Systems, yur@emcraft.com
* Alexander Potashev, Emcraft Systems, aspotashev@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
*/
/*
* Configuration settings for the STMicroelectronic STM3220G-EVAL board.
*/
#ifndef __CONFIG_H
#define __CONFIG_H
/*
* Disable debug messages
*/
#undef DEBUG
/*
* This is an ARM Cortex-M4 CPU core. Also use the common Cortex-M3 code.
*/
#define CONFIG_SYS_ARMCORTEXM3
#define CONFIG_SYS_ARMCORTEXM4
/*
* This is the STM32-F4 device
*/
#define CONFIG_SYS_STM32
/*
* Enable GPIO driver
*/
#define CONFIG_STM32F2_GPIO
/*
* Display CPU and Board information
*/
#define CONFIG_DISPLAY_CPUINFO 1
#define CONFIG_DISPLAY_BOARDINFO 1
#define CONFIG_SYS_BOARD_REV_STR "Rev 2.A"
/*
* Monitor prompt
*/
#define CONFIG_SYS_PROMPT "STM3240G-EVAL> "
/*
* We want to call the CPU specific initialization
*/
#define CONFIG_ARCH_CPU_INIT
/*
* Clock configuration (see mach-stm32/clock.c for details):
* - use PLL as the system clock;
* - use HSE as the PLL source;
* - configure PLL to get 168MHz system clock.
*/
#define CONFIG_STM32_SYS_CLK_PLL
#define CONFIG_STM32_PLL_SRC_HSE
#define CONFIG_STM32_HSE_HZ 25000000 /* 25 MHz */
#define CONFIG_STM32_PLL_M 25
#define CONFIG_STM32_PLL_N 336
#define CONFIG_STM32_PLL_P 2
#define CONFIG_STM32_PLL_Q 7
/*
* Number of clock ticks in 1 sec
*/
#define CONFIG_SYS_HZ 1000
/*
* Enable/disable h/w watchdog
*/
#undef CONFIG_HW_WATCHDOG
/*
* No interrupts
*/
#undef CONFIG_USE_IRQ
/*
* Memory layout configuration
*/
#define CONFIG_MEM_NVM_BASE 0x00000000
#define CONFIG_MEM_NVM_LEN (1024 * 1024)
#define CONFIG_MEM_RAM_BASE 0x20000000
#define CONFIG_MEM_RAM_LEN (20 * 1024)
#define CONFIG_MEM_RAM_BUF_LEN (88 * 1024)
#define CONFIG_MEM_MALLOC_LEN (16 * 1024)
#define CONFIG_MEM_STACK_LEN (4 * 1024)
/*
* malloc() pool size
*/
#define CONFIG_SYS_MALLOC_LEN CONFIG_MEM_MALLOC_LEN
#define FSMC_NOR_PSRAM_CS_ADDR(n) \
(0x60000000 + ((n) - 1) * 0x4000000)
/*
* Configuration of the external PSRAM memory
*/
#define CONFIG_NR_DRAM_BANKS 1
#define CONFIG_SYS_RAM_SIZE (32 * 1024 * 1024)
#define CONFIG_SYS_RAM_CS 2
#undef CONFIG_SYS_RAM_BURST
#define CONFIG_SYS_FSMC_PSRAM_BCR 0x00005059
#define CONFIG_SYS_FSMC_PSRAM_BTR 0x10000804
#define CONFIG_SYS_FSMC_PSRAM_BWTR 0x10000704
#define CONFIG_FSMC_NOR_PSRAM_CS2_ENABLE
#define CONFIG_SYS_RAM_BASE FSMC_NOR_PSRAM_CS_ADDR(CONFIG_SYS_RAM_CS)
#undef CONFIG_LCD
#ifdef CONFIG_LCD
#define LCD_BPP LCD_COLOR16
#define CONFIG_BMP_16BPP 1
#define CONFIG_SPLASH_SCREEN 1
#define CONFIG_CMD_BMP
#define CONFIG_FB_ADDR \
(CONFIG_SYS_RAM_BASE + CONFIG_SYS_RAM_SIZE - \
roundup(calc_fbsize(), PAGE_SIZE))
#define CONFIG_LCD_CS 3
#define CONFIG_LCD_FSMC_BCR \
STM32_FSMC_BCR_MBKEN | \
STM32_FSMC_BCR_WREN | \
(STM32_FSMC_BCR_MWID_16 << STM32_FSMC_BCR_MWID_BIT)
#define CONFIG_LCD_FSMC_BTR \
(1 << STM32_FSMC_BTR_ADDRST_BIT) | \
(0 << STM32_FSMC_BTR_ADDHOLD_BIT) | \
(9 << STM32_FSMC_BTR_DATAST_BIT) | \
(0 << STM32_FSMC_BTR_BUSTURN_BIT) | \
(0 << STM32_FSMC_BTR_CLKDIV_BIT) | \
(0 << STM32_FSMC_BTR_DATLAT_BIT) | \
STM32_FSMC_BWTR_ACCMOD_A
#define CONFIG_LCD_FSMC_BWTR \
(1 << STM32_FSMC_BWTR_ADDRST_BIT) | \
(0 << STM32_FSMC_BWTR_ADDHOLD_BIT) | \
(9 << STM32_FSMC_BWTR_DATAST_BIT) | \
(0 << STM32_FSMC_BWTR_CLKDIV_BIT) | \
(0 << STM32_FSMC_BWTR_DATLAT_BIT) | \
STM32_FSMC_BWTR_ACCMOD_A
#define CONFIG_FSMC_NOR_PSRAM_CS3_ENABLE
#define CONFIG_LCD_ILI932x
#define CONFIG_LCD_ILI932x_BASE FSMC_NOR_PSRAM_CS_ADDR(CONFIG_LCD_CS)
#define CONFIG_LCD_ILI932x_DOUBLE_BUFFER