Commit d4651b1a authored by Yuri Tikhonov's avatar Yuri Tikhonov
Browse files

RT73025. stm32f2_gpio: change API, and add support for FSMC



Rationale: to support external RAM there'll be again (like in MAC)
a plenty of GPIOs which should be configured. Don't want to redfine
the GPIO descriptor structure (port + pin), let's have this struct
as a part of STM32F2 GPIO Driver API.
Signed-off-by: default avatarYuri Tikhonov <yur@emcraft.com>
parent 957a77c0
......@@ -91,6 +91,11 @@
*/
#define STM32F2_GPIO_AF_MAC 0x0B
/*
* AF12 selection
*/
#define STM32F2_GPIO_AF_FSMC 0x0C
/*
* GPIO register map
*/
......@@ -123,13 +128,14 @@ static const u32 af_val[] = {
STM32F2_GPIO_AF_USART1, STM32F2_GPIO_AF_USART2, STM32F2_GPIO_AF_USART3,
STM32F2_GPIO_AF_USART4, STM32F2_GPIO_AF_USART5, STM32F2_GPIO_AF_USART6,
STM32F2_GPIO_AF_MAC,
0
0,
STM32F2_GPIO_AF_FSMC
};
/*
* Configure the specified GPIO for the specified role
*/
int stm32f2_gpio_config(unsigned int port, unsigned int pin,
int stm32f2_gpio_config(struct stm32f2_gpio_dsc *dsc,
enum stm32f2_gpio_role role)
{
volatile struct stm32f2_gpio_regs *gpio_regs;
......@@ -141,8 +147,10 @@ int stm32f2_gpio_config(unsigned int port, unsigned int pin,
/*
* Check params
*/
if (port > 8 || pin > 15) {
printf("%s: incorrect params %d.%d.\n", __func__, port, pin);
if (!dsc || dsc->port > 8 || dsc->pin > 15) {
printf("%s: incorrect params %d.%d.\n", __func__,
dsc ? dsc->port : -1,
dsc ? dsc->pin : -1);
rv = -EINVAL;
goto out;
}
......@@ -163,6 +171,7 @@ int stm32f2_gpio_config(unsigned int port, unsigned int pin,
break;
case STM32F2_GPIO_ROLE_ETHERNET:
case STM32F2_GPIO_ROLE_MCO:
case STM32F2_GPIO_ROLE_FSMC:
otype = STM32F2_GPIO_OTYPE_PP;
ospeed = STM32F2_GPIO_SPEED_100M;
pupd = STM32F2_GPIO_PUPD_NO;
......@@ -177,23 +186,23 @@ int stm32f2_gpio_config(unsigned int port, unsigned int pin,
* Get reg base
*/
rcc_regs = (struct stm32f2_rcc_regs *)STM32F2_RCC_BASE;
gpio_regs = (struct stm32f2_gpio_regs *)io_base[port];
gpio_regs = (struct stm32f2_gpio_regs *)io_base[dsc->port];
/*
* Enable GPIO clocks
*/
rcc_regs->ahb1enr |= 1 << port;
rcc_regs->ahb1enr |= 1 << dsc->port;
if (role != STM32F2_GPIO_ROLE_MCO) {
/*
* Connect PXy to the specified controller (role)
*/
i = (pin & 0x07) * 4;
gpio_regs->afr[pin >> 3] &= ~(0xF << i);
gpio_regs->afr[pin >> 3] |= af_val[role] << i;
i = (dsc->pin & 0x07) * 4;
gpio_regs->afr[dsc->pin >> 3] &= ~(0xF << i);
gpio_regs->afr[dsc->pin >> 3] |= af_val[role] << i;
}
i = pin * 2;
i = dsc->pin * 2;
/*
* Set Alternative function mode
......
......@@ -356,7 +356,7 @@ struct stm_mac_gpio {
* ETH_MII_RXD3 ---------------------> PH7
* ETH_MII_RX_ER --------------------> PI10
*/
static struct stm_mac_gpio mac_gpio[] = {
static struct stm32f2_gpio_dsc mac_gpio[] = {
{0, 1}, {0, 2}, {0, 7},
{1, 5}, {1, 8},
{2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5},
......@@ -775,14 +775,15 @@ static void stm_mac_address_set(struct stm_eth_dev *mac)
/*
* Init GPIOs used by MAC
*/
static void stm_mac_gpio_init(struct stm_eth_dev *mac)
static int stm_mac_gpio_init(struct stm_eth_dev *mac)
{
static struct stm32f2_gpio_dsc mco_gpio = {0, 8};
static int gpio_inited;
volatile struct stm32f2_rcc_regs *rcc_regs;
volatile struct stm32f2_syscfg_regs *syscfg_regs;
u32 val;
int i;
int i, rv;
/*
* Init GPIOs only once at start. Otherwise, reiniting then on
......@@ -792,8 +793,10 @@ static void stm_mac_gpio_init(struct stm_eth_dev *mac)
* on wires. Probably, some synchronization with PHY is lost if
* we do this GPIO re-initialization.
*/
if (gpio_inited)
if (gpio_inited) {
rv = 0;
goto out;
}
/*
* Get reg bases, enable SYSCFG clock
......@@ -806,7 +809,9 @@ static void stm_mac_gpio_init(struct stm_eth_dev *mac)
/*
* Configure MC0: PA8
*/
stm32f2_gpio_config(0, 8, STM32F2_GPIO_ROLE_MCO);
rv = stm32f2_gpio_config(&mco_gpio, STM32F2_GPIO_ROLE_MCO);
if (rv != 0)
goto out;
/*
* Output HSE clock (25MHz) on MCO pin (PA8) to clock the PHY
......@@ -833,13 +838,16 @@ static void stm_mac_gpio_init(struct stm_eth_dev *mac)
* Set GPIOs Alternative function
*/
for (i = 0; i < sizeof(mac_gpio)/sizeof(mac_gpio[0]); i++) {
stm32f2_gpio_config(mac_gpio[i].port, mac_gpio[i].pin,
STM32F2_GPIO_ROLE_ETHERNET);
rv = stm32f2_gpio_config(&mac_gpio[i],
STM32F2_GPIO_ROLE_ETHERNET);
if (rv != 0)
goto out;
}
gpio_inited = 1;
rv = 0;
out:
return;
return rv;
}
/*
......@@ -854,7 +862,9 @@ static int stm_mac_hw_init(struct stm_eth_dev *mac)
/*
* Init GPIOs
*/
stm_mac_gpio_init(mac);
rv = stm_mac_gpio_init(mac);
if (rv != 0)
goto out;
/*
* Enable Ethernet clocks
......
......@@ -195,6 +195,10 @@ static volatile struct stm32f2_usart_regs *usart_regs;
*/
int serial_init(void)
{
static struct stm32f2_gpio_dsc tx_gpio = { USART_TX_IO_PORT,
USART_TX_IO_PIN };
static struct stm32f2_gpio_dsc rx_gpio = { USART_RX_IO_PORT,
USART_RX_IO_PIN };
static volatile u32 *usart_enr;
static volatile struct stm32f2_rcc_regs *rcc_regs;
......@@ -216,12 +220,10 @@ int serial_init(void)
/*
* Configure GPIOs
*/
rv = stm32f2_gpio_config(USART_TX_IO_PORT, USART_TX_IO_PIN,
gpio_role[USART_PORT]);
rv = stm32f2_gpio_config(&tx_gpio, gpio_role[USART_PORT]);
if (rv != 0)
goto out;
rv = stm32f2_gpio_config(USART_RX_IO_PORT, USART_RX_IO_PIN,
gpio_role[USART_PORT]);
rv = stm32f2_gpio_config(&rx_gpio, gpio_role[USART_PORT]);
if (rv != 0)
goto out;
......
......@@ -23,23 +23,32 @@
#define _STM32F2_GPIO_H_
/*
* GPIO roles (alternative functions)
* GPIO roles (alternative functions); role determines by whom GPIO is used
*/
enum stm32f2_gpio_role {
STM32F2_GPIO_ROLE_USART1, /* GPIO is used by USART1 */
STM32F2_GPIO_ROLE_USART2, /* GPIO is used by USART2 */
STM32F2_GPIO_ROLE_USART3, /* GPIO is used by USART3 */
STM32F2_GPIO_ROLE_USART4, /* GPIO is used by USART4 */
STM32F2_GPIO_ROLE_USART5, /* GPIO is used by USART5 */
STM32F2_GPIO_ROLE_USART6, /* GPIO is used by USART6 */
STM32F2_GPIO_ROLE_ETHERNET, /* GPIO is used by MAC */
STM32F2_GPIO_ROLE_MCO /* GPIO is used for MC ext output clk */
STM32F2_GPIO_ROLE_USART1, /* USART1 */
STM32F2_GPIO_ROLE_USART2, /* USART2 */
STM32F2_GPIO_ROLE_USART3, /* USART3 */
STM32F2_GPIO_ROLE_USART4, /* USART4 */
STM32F2_GPIO_ROLE_USART5, /* USART5 */
STM32F2_GPIO_ROLE_USART6, /* USART6 */
STM32F2_GPIO_ROLE_ETHERNET, /* MAC */
STM32F2_GPIO_ROLE_MCO, /* MC external output clock */
STM32F2_GPIO_ROLE_FSMC /* FSMC static memory controller */
};
/*
* GPIO descriptor
*/
struct stm32f2_gpio_dsc {
u32 port; /* GPIO port */
u32 pin; /* GPIO pin */
};
/*
* Configure the specified GPIO for the specified role
*/
int stm32f2_gpio_config(unsigned int port, unsigned int pin,
int stm32f2_gpio_config(struct stm32f2_gpio_dsc *gpio_dsc,
enum stm32f2_gpio_role role);
#endif /* _STM32F2_GPIO_H_ */
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