Commit c649e71d authored by Sergei Poselenov's avatar Sergei Poselenov
Browse files

Merge branch 'master' of ocean:/SR/git/A2F/u-boot

parents 8bd0fc38 5e8aa329
......@@ -31,32 +31,12 @@
#if (CONFIG_NR_DRAM_BANKS > 0)
/*
* Warn if DRAM configuration isn't set, and use the following defaults:
*
* IS61WV102416BLL at Bank1 SRAM 2:
* - 16 bit data bus, SRAM, Mode 1, Enabled.
* - CLK period is HCLK (8.4s);
* - ADDSET = 0 x CLK;
* - DATASET = 2 x CLK (16.8ns);
* - BUSTURN = 1 x CLK (8.4ns).
* - these timings used both for read & write accesses (not-extended
* mode - WTR register isn't used).
* Check if RAM configured
*/
# if !defined(CONFIG_SYS_RAM_CS) || !defined(CONFIG_SYS_FSMC_BCR) || \
!defined(CONFIG_SYS_FSMC_BTR)
# warning "Incorrect FSMC configuration. Using defaults."
# undef CONFIG_SYS_RAM_CS
# undef CONFIG_SYS_FSMC_BCR
# undef CONFIG_SYS_FSMC_BTR
# undef CONFIG_SYS_FSMC_BWR
# define CONFIG_SYS_RAM_CS 2
# define CONFIG_SYS_FSMC_BCR (STM32_FSMC_BCR_WREN | \
(STM32_FSMC_BCR_MWID_16 << \
STM32_FSMC_BCR_MWID_BIT) | \
STM32_FSMC_BCR_MBKEN)
# define CONFIG_SYS_FSMC_BTR (1 << STM32_FSMC_BTR_BUSTURN_BIT) | \
(2 << STM32_FSMC_BTR_DATAST_BIT)
# endif /* !CONFIG_SYS_RAM_CS || !CONFIG_SYS_FSMC_BCR || !CONFIG_SYS_FSMC_BTR */
# if !defined(CONFIG_SYS_RAM_CS) || !defined(CONFIG_SYS_FSMC_PSRAM_BCR) || \
!defined(CONFIG_SYS_FSMC_PSRAM_BTR)
# error "Incorrect FSMC configuration."
# endif
#endif /* CONFIG_NR_DRAM_BANKS */
/*
......@@ -66,45 +46,97 @@
DECLARE_GLOBAL_DATA_PTR;
#if (CONFIG_NR_DRAM_BANKS > 0) || !defined(CONFIG_SYS_NO_FLASH)
/*
* External SRAM GPIOs:
* External SRAM GPIOs for FSMC:
*
* +-----------------+------------------+----------------+----------------+
* | PD0 <->FSMC_D2 | PE0 <->FSMC_NBL0 | PF0 <->FSMC_A0 | PG0<->FSMC_A10 |
* | PD1 <->FSMC_D3 | PE1 <->FSMC_NBL1 | PF1 <->FSMC_A1 | PG1<->FSMC_A11 |
| PD4 <->FSMC_NOE | PE3 <->FSMC_A19 | PF2 <->FSMC_A2 | PG2<->FSMC_A12 |
| PD5 <->FSMC_NWE | PE4 <->FSMC_A20 | PF3 <->FSMC_A3 | PG3<->FSMC_A13 |
* | PD8 <->FSMC_D13 | PE7 <->FSMC_D4 | PF5 <->FSMC_A5 | PG5<->FSMC_A15 |
* | PD9 <->FSMC_D14 | PE8 <->FSMC_D5 | PF12<->FSMC_A6 | PG9<->FSMC_NE2 |
* | PD10<->FSMC_D15 | PE9 <->FSMC_D6 | PF13<->FSMC_A7 +----------------+
* | PD11<->FSMC_A16 | PE10<->FSMC_D7 | PF14<->FSMC_A8 |
* | PD12<->FSMC_A17 | PE11<->FSMC_D8 | PF15<->FSMC_A9 |
* | PD13<->FSMC_A18 | PE12<->FSMC_D9 +----------------+
* | PD14<->FSMC_D0 | PE13<->FSMC_D10 |
* | PD15<->FSMC_D1 | PE14<->FSMC_D11 |
* +-----------------+ PE15<->FSMC_D12 |
* +------------------+
* D0..D15, A0..A23, NE2/1, NOE, NWE, NBL1/0, CLK, NL, NWAIT
*/
static struct stm32f2_gpio_dsc fsmc_gpio[] = {
{3, 0}, {3, 1}, {3, 4}, {3, 5}, {3, 8}, {3, 9}, {3, 10}, {3, 11},
{3, 12}, {3, 13}, {3, 14}, {3, 15},
{4, 0}, {4, 1}, {4, 3}, {4, 4}, {4, 7}, {4, 8}, {4, 9}, {4, 10},
{4, 11}, {4, 12}, {4, 13}, {4, 14}, {4, 15},
{5, 0}, {5, 1}, {5, 2}, {5, 3}, {5, 4}, {5, 5}, {5, 12}, {5, 13},
{5, 14}, {5, 15},
{6, 0}, {6, 1}, {6, 2}, {6, 3}, {6, 4}, {6, 5}, {6, 9}
{STM32F2_GPIO_PORT_B, STM32F2_GPIO_PIN_7},
{STM32F2_GPIO_PORT_D, STM32F2_GPIO_PIN_0},
{STM32F2_GPIO_PORT_D, STM32F2_GPIO_PIN_1},
{STM32F2_GPIO_PORT_D, STM32F2_GPIO_PIN_3},
{STM32F2_GPIO_PORT_D, STM32F2_GPIO_PIN_4},
{STM32F2_GPIO_PORT_D, STM32F2_GPIO_PIN_5},
{STM32F2_GPIO_PORT_D, STM32F2_GPIO_PIN_6},
{STM32F2_GPIO_PORT_D, STM32F2_GPIO_PIN_7},
{STM32F2_GPIO_PORT_D, STM32F2_GPIO_PIN_8},
{STM32F2_GPIO_PORT_D, STM32F2_GPIO_PIN_9},
{STM32F2_GPIO_PORT_D, STM32F2_GPIO_PIN_10},
{STM32F2_GPIO_PORT_D, STM32F2_GPIO_PIN_11},
{STM32F2_GPIO_PORT_D, STM32F2_GPIO_PIN_12},
{STM32F2_GPIO_PORT_D, STM32F2_GPIO_PIN_13},
{STM32F2_GPIO_PORT_D, STM32F2_GPIO_PIN_14},
{STM32F2_GPIO_PORT_D, STM32F2_GPIO_PIN_15},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_0},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_1},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_2},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_3},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_4},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_5},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_6},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_7},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_8},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_9},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_10},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_11},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_12},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_13},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_14},
{STM32F2_GPIO_PORT_E, STM32F2_GPIO_PIN_15},
{STM32F2_GPIO_PORT_F, STM32F2_GPIO_PIN_0},
{STM32F2_GPIO_PORT_F, STM32F2_GPIO_PIN_1},
{STM32F2_GPIO_PORT_F, STM32F2_GPIO_PIN_2},
{STM32F2_GPIO_PORT_F, STM32F2_GPIO_PIN_3},
{STM32F2_GPIO_PORT_F, STM32F2_GPIO_PIN_4},
{STM32F2_GPIO_PORT_F, STM32F2_GPIO_PIN_5},
{STM32F2_GPIO_PORT_F, STM32F2_GPIO_PIN_12},
{STM32F2_GPIO_PORT_F, STM32F2_GPIO_PIN_13},
{STM32F2_GPIO_PORT_F, STM32F2_GPIO_PIN_14},
{STM32F2_GPIO_PORT_F, STM32F2_GPIO_PIN_15},
{STM32F2_GPIO_PORT_G, STM32F2_GPIO_PIN_0},
{STM32F2_GPIO_PORT_G, STM32F2_GPIO_PIN_1},
{STM32F2_GPIO_PORT_G, STM32F2_GPIO_PIN_2},
{STM32F2_GPIO_PORT_G, STM32F2_GPIO_PIN_3},
{STM32F2_GPIO_PORT_G, STM32F2_GPIO_PIN_4},
{STM32F2_GPIO_PORT_G, STM32F2_GPIO_PIN_5},
{STM32F2_GPIO_PORT_G, STM32F2_GPIO_PIN_9}
};
#endif
/*
* Early hardware init.
*/
int board_init(void)
{
int rv = 0;
#if (CONFIG_NR_DRAM_BANKS > 0) || !defined(CONFIG_SYS_NO_FLASH)
/*
* TBD
* Some external memory is used. Connect GPIOs to FSMC controller
*/
int i;
return 0;
for (i = 0; i < sizeof(fsmc_gpio)/sizeof(fsmc_gpio[0]); i++) {
rv = stm32f2_gpio_config(&fsmc_gpio[i],
STM32F2_GPIO_ROLE_FSMC);
if (rv != 0)
break;
}
/*
* Enable FSMC interface clock
*/
if (rv == 0)
STM32_RCC->ahb3enr |= STM32_RCC_ENR_FSMC;
#endif
return rv;
}
/*
......@@ -123,9 +155,25 @@ int checkboard(void)
*/
int misc_init_r(void)
{
#if !defined(CONFIG_SYS_NO_FLASH)
int i, rv;
/*
* TBD
* Configure FSMC Flash block
*/
i = CONFIG_SYS_FLASH_CS - 1;
/*
* FIXME: not sure if this fake read is necessary here
*/
rv = STM32_FSMC->cs[i].bcr;
STM32_FSMC->cs[i].bcr = CONFIG_SYS_FSMC_FLASH_BCR;
STM32_FSMC->cs[i].btr = CONFIG_SYS_FSMC_FLASH_BTR;
# if defined(CONFIG_SYS_FSMC_FLASH_BWR)
STM32_FSMC->wt[i].wtr = CONFIG_SYS_FSMC_FLASH_BWR;
# endif
#endif /* CONFIG_SYS_NO_FLASH */
return 0;
}
......@@ -138,39 +186,76 @@ int dram_init(void)
int rv = 0;
#if (CONFIG_NR_DRAM_BANKS > 0)
int i;
static struct stm32f2_gpio_dsc ctrl_gpio = {STM32F2_GPIO_PORT_I,
STM32F2_GPIO_PIN_9};
int i;
/*
* Connect GPIOs to FSMC controller
* Configure FSMC PSRAM block
*/
for (i = 0; i < sizeof(fsmc_gpio)/sizeof(fsmc_gpio[0]); i++) {
rv = stm32f2_gpio_config(&fsmc_gpio[i],
STM32F2_GPIO_ROLE_FSMC);
if (rv != 0)
goto out;
}
i = CONFIG_SYS_RAM_CS - 1;
/*
* Enable FSMC interface clock
* Fake BCR read; if don't do this, then BCR remains configured
* with defaults.
*/
STM32_RCC->ahb3enr |= STM32_RCC_ENR_FSMC;
rv = STM32_FSMC->cs[i].bcr;
/* Step.1 */
STM32_FSMC->cs[i].bcr = CONFIG_SYS_FSMC_PSRAM_BCR;
STM32_FSMC->cs[i].btr = CONFIG_SYS_FSMC_PSRAM_BTR;
# if defined(CONFIG_SYS_FSMC_PSRAM_BWR)
STM32_FSMC->wt[i].wtr = CONFIG_SYS_FSMC_PSRAM_BWR;
# endif
rv = stm32f2_gpio_config(&ctrl_gpio, STM32F2_GPIO_ROLE_GPOUT);
if (rv != 0)
goto out;
# if defined(CONFIG_SYS_RAM_BURST)
/*
* Configure FSMC
* FIXME: all this hardcoded stuff, and wiki 'Step.X' remarks...
*/
i = CONFIG_SYS_RAM_CS - 1;
/* Step.2 */
stm32f2_gpout_set(&ctrl_gpio, 1);
/* Step.3 */
*(volatile u8 *)(CONFIG_SYS_RAM_BASE + 0x4101F) = 0;
/* Step.4-5 */
stm32f2_gpout_set(&ctrl_gpio, 0);
/* Step.6 */
STM32_FSMC->cs[i].bcr = 0x00087959;
STM32_FSMC->cs[i].btr = 0x0010FFFF;
/* Step.7 */
rv = *(volatile u8 *)(CONFIG_SYS_RAM_BASE + 0x000000);
/* Step.8 */
STM32_FSMC->cs[i].bcr = 0x00005059;
STM32_FSMC->cs[i].btr = 0x100106F2;
STM32_FSMC->wt[i].wtr = 0x100107F2;
/* Step.9 */
stm32f2_gpout_set(&ctrl_gpio, 1);
/* Step.10 */
*(volatile u8 *)(CONFIG_SYS_RAM_BASE + 0x4101F) = 0;
/* Step.11 */
stm32f2_gpout_set(&ctrl_gpio, 0);
/* Step.12 */
STM32_FSMC->cs[i].bcr = 0x00087959;
STM32_FSMC->cs[i].btr = 0x0010FFFF;
# else
/*
* Fake BCR read; if don't do this, then BCR remains configured
* with defaults.
* Switch PSRAM in the Asyncronous Read/Write Mode
*/
rv = STM32_FSMC->cs[i].bcr;
STM32_FSMC->cs[i].bcr = CONFIG_SYS_FSMC_BCR;
STM32_FSMC->cs[i].btr = CONFIG_SYS_FSMC_BTR;
#if defined(CONFIG_SYS_FSMC_BWR)
STM32_FSMC->wt[i].wtr = CONFIG_SYS_FSMC_BWR;
#endif
stm32f2_gpout_set(&ctrl_gpio, 0);
# endif /* CONFIG_SYS_RAM_BURST */
/*
* Fill in global info with description of SRAM configuration
......@@ -181,6 +266,7 @@ int dram_init(void)
rv = 0;
out:
#endif /* CONFIG_NR_DRAM_BANKS */
return rv;
}
......
......@@ -29,7 +29,20 @@
* Flash data area definitions
*/
#define STM32_FLASH_BASE 0x08000000
#define STM32_FLASH_SIZE (8*128*1024)
#define STM32_FLASH_SIZE ((4 * 16 + 64 + 7 * 128) * 1024)
/*
* This array defines the layout of the Embedded Flash on the STM32F2x chips
*/
static u32 flash_bsize[] = {
[0 ... 3] = 16 * 1024,
[4] = 64 * 1024,
[5 ... 11] = 128 * 1024
};
/*
* Number of flash blocks for STM32F2x chips
*/
#define STM32_FLASH_BLOCKS (sizeof(flash_bsize)/sizeof(flash_bsize[0]))
/*
* Flash registers base
......@@ -40,15 +53,15 @@
* Flash register map
*/
struct stm32_flash_regs {
u32 acr; /* Access control */
u32 keyr; /* Key */
u32 optkeyr; /* Option key */
u32 sr; /* Status */
u32 cr; /* Control */
u32 optcr; /* Option control */
u32 acr; /* Access control */
u32 keyr; /* Key */
u32 optkeyr; /* Option key */
u32 sr; /* Status */
u32 cr; /* Control */
u32 optcr; /* Option control */
};
#define STM32_FLASH_REGS ((volatile struct stm32_flash_regs *) \
STM32_FLASHREGS_BASE)
#define STM32_FLASH_REGS ((volatile struct stm32_flash_regs *) \
STM32_FLASHREGS_BASE)
/*
* Flash CR definitions
......@@ -69,16 +82,16 @@ struct stm32_flash_regs {
/*
* Flash ACR definitions
*/
#define STM32_FLASH_ACR_LAT_BIT 0 /* Latency */
#define STM32_FLASH_ACR_LAT_MSK 0x3
#define STM32_FLASH_ACR_PRFTEN (1 << 8) /* Prefetch enable */
#define STM32_FLASH_ACR_ICEN (1 << 9) /* Instruction cache enable */
#define STM32_FLASH_ACR_LAT_BIT 0 /* Latency */
#define STM32_FLASH_ACR_LAT_MSK 0x7
#define STM32_FLASH_ACR_PRFTEN (1 << 8) /* Prefetch enable */
#define STM32_FLASH_ACR_ICEN (1 << 9) /* Instruction cache enable */
/*
* Flash KEYR definitions
*/
#define STM32_FLASH_KEYR_KEY1 0x45670123 /* KEY1 value to unlock CR */
#define STM32_FLASH_KEYR_KEY2 0xCDEF89AB /* KEY2 value to unlock CR */
#define STM32_FLASH_KEYR_KEY1 0x45670123 /* KEY1 to unlock CR */
#define STM32_FLASH_KEYR_KEY2 0xCDEF89AB /* KEY2 to unlock CR */
/*
* Flash SR definitions
......@@ -115,33 +128,81 @@ stm32_flash_cr_lock(void)
}
/*
* Erase the whole embedded flash of the STM32.
* Given the flash address, return the block number.
* Return error if the address is not a start block address.
*/
static s32 stm32_flash_get_block(u8 *addr)
{
s32 i = 0;
u8 *base = (u8 *)STM32_FLASH_BASE;
while (i < STM32_FLASH_BLOCKS) {
if (addr == base)
break;
base += flash_bsize[i];
i++;
}
if (i == STM32_FLASH_BLOCKS)
i = -EINVAL;
return i;
}
/*
* Erase the embedded flash of the STM32. Start block is calculated from the
* given offset, end block - from size.
*/
static int __attribute__((section(".ramcode")))
static s32 __attribute__((section(".ramcode")))
__attribute__ ((long_call))
stm32_flash_erase(uint32_t offset, uint32_t size)
stm32_flash_erase(u32 offset, u32 size)
{
int32_t ret = -EBUSY;
/* No sanity check of address here, proceed to erase */
s32 ret;
s32 n, num;
u32 erasesize;
if ((n = stm32_flash_get_block((u8 *)offset)) < 0) {
printf("%s: Address %#x is not block-aligned\n", __func__,
offset);
ret = n;
goto xit;
}
/* Calculate the number of blocks to erase */
erasesize = 0;
num = n;
while (erasesize < size) {
erasesize += flash_bsize[num];
num++;
}
/* Check there is no pending operations */
if (STM32_FLASH_REGS->sr & STM32_FLASH_SR_BSY) {
printf("%s: Flash is busy\n", __func__);
ret = -EBUSY;
goto xit;
}
stm32_flash_cr_unlock();
STM32_FLASH_REGS->cr |= STM32_FLASH_CR_MER;
STM32_FLASH_REGS->cr |= STM32_FLASH_CR_START;
stm32_flash_cr_unlock();
/*
* Warning! As soon as the erase operation starts, you can't access
* U-Boot functions except of marked as ".ramcode".
*/
while (STM32_FLASH_REGS->sr & STM32_FLASH_SR_BSY)
;
while (n < num) {
STM32_FLASH_REGS->cr &= ~(STM32_FLASH_CR_SECT_MSK <<
STM32_FLASH_CR_SECT_SHIFT);
STM32_FLASH_REGS->cr |= ((n << STM32_FLASH_CR_SECT_SHIFT) |
STM32_FLASH_CR_SER);
STM32_FLASH_REGS->cr |= STM32_FLASH_CR_START;
/*
* Warning! As soon as the erase operation starts, you can't
* access U-Boot functions except of marked as ".ramcode"!
*/
while (STM32_FLASH_REGS->sr & STM32_FLASH_SR_BSY)
;
n++;
}
STM32_FLASH_REGS->cr &= ~STM32_FLASH_CR_MER;
STM32_FLASH_REGS->cr &= ~(STM32_FLASH_CR_SER |
(STM32_FLASH_CR_SECT_MSK << STM32_FLASH_CR_SECT_SHIFT));
stm32_flash_cr_lock();
ret = 0;
......@@ -149,22 +210,23 @@ xit:
return ret;
}
static int __attribute__((section(".ramcode")))
static s32 __attribute__((section(".ramcode")))
__attribute__ ((long_call))
stm32_flash_program(uint32_t offset, void *buf, uint32_t size)
stm32_flash_program(u32 offset, void *buf, u32 size)
{
uint32_t *src = (uint32_t *)buf;
uint32_t *dst = (uint32_t *)offset;
/* I know I can read 1-3 bytes beyond the input buffer, but this is OK */
uint32_t words = (size + sizeof(uint32_t) - 1)/ sizeof(uint32_t);
int32_t ret = -EBUSY;
u32 *src = (u32 *)buf;
u32 *dst = (u32 *)offset;
/* I can read 1-3 bytes beyond the input buffer, but this is OK */
u32 words = (size + sizeof(u32) - 1) / sizeof(u32);
s32 ret;
/* No sanity check on flash address here, proceed to program */
/* Check there is no pending operations */
if (STM32_FLASH_REGS->sr & STM32_FLASH_SR_BSY)
if (STM32_FLASH_REGS->sr & STM32_FLASH_SR_BSY) {
ret = -EBUSY;
goto xit;
}
stm32_flash_cr_unlock();
STM32_FLASH_REGS->cr |= STM32_FLASH_CR_PG;
......@@ -219,16 +281,17 @@ void envm_init(void)
* Note that we need for this function to reside in RAM since it
* will be used to self-upgrade U-boot in internal Flash.
*/
unsigned int __attribute__((section(".ramcode")))
u32 __attribute__((section(".ramcode")))
__attribute__ ((long_call))
envm_write(uint32_t offset, void * buf, uint32_t size)
envm_write(u32 offset, void * buf, u32 size)
{
int32_t ret = 0;
s32 ret = 0;
/* Sanity check */
/* Basic sanity check. More checking in the "get_block" routine */
if ((offset < STM32_FLASH_BASE) ||
((offset + size) > (STM32_FLASH_BASE + STM32_FLASH_SIZE))) {
printf("Offset %#x is not in flash or size %d is too big\n", offset, size);
printf("%s: Address %#x is not in flash or size %d is too big\n",
__func__, offset, size);
goto xit;
}
......
......@@ -106,8 +106,7 @@ struct stm32f2_gpio_regs {
u32 pupdr; /* GPIO port pull-up/pull-down */
u32 idr; /* GPIO port input data */
u32 odr; /* GPIO port output data */
u16 bsrrl; /* GPIO port bit set/reset low */
u16 bsrrh; /* GPIO port bit set/reset high */
u32 bsrr; /* GPIO port bit set/reset */
u32 lckr; /* GPIO port configuration lock */
u32 afr[2]; /* GPIO alternate function */
};
......@@ -124,12 +123,13 @@ static const unsigned long io_base[] = {
/*
* AF values (note, indexed by enum stm32f2_gpio_role)
*/
static const u32 af_val[] = {
static const u32 af_val[STM32F2_GPIO_ROLE_LAST] = {
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,
STM32F2_GPIO_AF_FSMC
(u32)-1,
STM32F2_GPIO_AF_FSMC,
(u32)-1
};
/*
......@@ -140,7 +140,7 @@ int stm32f2_gpio_config(struct stm32f2_gpio_dsc *dsc,
{
volatile struct stm32f2_gpio_regs *gpio_regs;
u32 otype, ospeed, pupd, i;
u32 otype, ospeed, pupd, mode, i;
int rv;
/*
......@@ -167,6 +167,7 @@ int stm32f2_gpio_config(struct stm32f2_gpio_dsc *dsc,
otype = STM32F2_GPIO_OTYPE_PP;
ospeed = STM32F2_GPIO_SPEED_50M;
pupd = STM32F2_GPIO_PUPD_UP;
mode = STM32F2_GPIO_MODE_AF;
break;
case STM32F2_GPIO_ROLE_ETHERNET:
case STM32F2_GPIO_ROLE_MCO:
......@@ -174,6 +175,13 @@ int stm32f2_gpio_config(struct stm32f2_gpio_dsc *dsc,
otype = STM32F2_GPIO_OTYPE_PP;
ospeed = STM32F2_GPIO_SPEED_100M;
pupd = STM32F2_GPIO_PUPD_NO;
mode = STM32F2_GPIO_MODE_AF;
break;
case STM32F2_GPIO_ROLE_GPOUT:
otype = STM32F2_GPIO_OTYPE_PP;
ospeed = STM32F2_GPIO_SPEED_50M;
pupd = STM32F2_GPIO_PUPD_NO;
mode = STM32F2_GPIO_MODE_OUT;
break;
default:
printf("%s: incorrect role %d.\n", __func__, role);
......@@ -191,7 +199,7 @@ int stm32f2_gpio_config(struct stm32f2_gpio_dsc *dsc,
*/
STM32_RCC->ahb1enr |= 1 << dsc->port;
if (role != STM32F2_GPIO_ROLE_MCO) {
if (af_val[role] != (u32)-1) {
/*
* Connect PXy to the specified controller (role)
*/
......@@ -206,7 +214,7 @@ int stm32f2_gpio_config(struct stm32f2_gpio_dsc *dsc,
* Set Alternative function mode
*/
gpio_regs->moder &= ~(0x3 << i);
gpio_regs->moder |= STM32F2_GPIO_MODE_AF << i;
gpio_regs->moder |= mode << i;
/*
* Output mode configuration
......@@ -231,3 +239,32 @@ out:
return rv;
}
/*
* Set GPOUT to the state specified (1, 0)
*/
int stm32f2_gpout_set(struct stm32f2_gpio_dsc *dsc, int state)
{
volatile struct stm32f2_gpio_regs *gpio_regs;
int rv;
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;
}
gpio_regs = (struct stm32f2_gpio_regs *)io_base[dsc->port];
rv = !!state;
if (rv) {
/* Set */
gpio_regs->bsrr = 1 << dsc->pin;
} else {
/* Reset */
gpio_regs->bsrr = 1 << (dsc->pin + 16);
}
out:
return rv;
}