Hi Bo
On 09/29/2017 08:24 AM, Bo Shen wrote:
> Hi Patrice,
> For this patch, overall I think you can use more generic method like
> define the parameter called ip_version in stm32_uart_info structure, and
> according to this information to covert base to different register map
> as following, then we can get rid of "stm32f4" in stm32_uart_info
> structure, and easy to extend if you have more versions.
>
> --->8---
> struct stm32_usart_v1 { }; (version 1 register map)
> struct stm32_usart_v2 { }; (version 2 register map)
>
> switch (ip_version) {
> case v1:
> struct stm32_usart_v1 *ptr = (struct stm32_usart_v1 *)base;
> break;
> case v2:
> struct stm32_usart_v1 *ptr = (struct stm32_usart_v1 *)base;
> break;
> }
> ---8<---
It's another way to solve this problem, i will check if it's more
efficient regarding code/data size
Thanks for the tips.
Patrice
>
> Best Regards,
> Bo Shen
>
> On 09/27/2017 06:44 AM, patrice.chot...@st.com wrote:
>> From: Patrice Chotard
>>
>> STM32F4 serial IP is similar to F7 and H7, but registers
>> are not located at the same offset and some feature are
>> only supported by F7 and H7 version.
>>
>> Registers offset must be added for each version and also
>> some flags indicated the supported feature.
>>
>> Update registers name to match with datasheet (sr to isr,
>> rx_dr to rdr and tx_dr to tdr) and remove unused regs
>> (cr2, gtpr, rtor, and rqr).
>>
>> Signed-off-by: Patrice Chotard
>> ---
>> drivers/serial/serial_stm32x7.c | 72
>> -
>> drivers/serial/serial_stm32x7.h | 38 ++
>> 2 files changed, 66 insertions(+), 44 deletions(-)
>>
>> diff --git a/drivers/serial/serial_stm32x7.c
>> b/drivers/serial/serial_stm32x7.c
>> index bafcc36..81a2308 100644
>> --- a/drivers/serial/serial_stm32x7.c
>> +++ b/drivers/serial/serial_stm32x7.c
>> @@ -17,67 +17,79 @@ DECLARE_GLOBAL_DATA_PTR;
>> static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
>> {
>> - struct stm32x7_serial_platdata *plat = dev->platdata;
>> - struct stm32_usart *const usart = plat->base;
>> + struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
>> + bool stm32f4 = plat->uart_info->stm32f4;
>> + fdt_addr_t base = plat->base;
>> u32 int_div, mantissa, fraction, oversampling;
>> int_div = DIV_ROUND_CLOSEST(plat->clock_rate, baudrate);
>> if (int_div < 16) {
>> oversampling = 8;
>> - setbits_le32(&usart->cr1, USART_CR1_OVER8);
>> + setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_OVER8);
>> } else {
>> oversampling = 16;
>> - clrbits_le32(&usart->cr1, USART_CR1_OVER8);
>> + clrbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_OVER8);
>> }
>> mantissa = (int_div / oversampling) << USART_BRR_M_SHIFT;
>> fraction = int_div % oversampling;
>> - writel(mantissa | fraction, &usart->brr);
>> + writel(mantissa | fraction, base + BRR_OFFSET(stm32f4));
>> return 0;
>> }
>> static int stm32_serial_getc(struct udevice *dev)
>> {
>> - struct stm32x7_serial_platdata *plat = dev->platdata;
>> - struct stm32_usart *const usart = plat->base;
>> + struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
>> + bool stm32f4 = plat->uart_info->stm32f4;
>> + fdt_addr_t base = plat->base;
>> - if ((readl(&usart->sr) & USART_SR_FLAG_RXNE) == 0)
>> + if ((readl(base + ISR_OFFSET(stm32f4)) & USART_SR_FLAG_RXNE) == 0)
>> return -EAGAIN;
>> - return readl(&usart->rd_dr);
>> + return readl(base + RDR_OFFSET(stm32f4));
>> }
>> static int stm32_serial_putc(struct udevice *dev, const char c)
>> {
>> - struct stm32x7_serial_platdata *plat = dev->platdata;
>> - struct stm32_usart *const usart = plat->base;
>> + struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
>> + bool stm32f4 = plat->uart_info->stm32f4;
>> + fdt_addr_t base = plat->base;
>> - if ((readl(&usart->sr) & USART_SR_FLAG_TXE) == 0)
>> + if ((readl(base + ISR_OFFSET(stm32f4)) & USART_SR_FLAG_TXE) == 0)
>> return -EAGAIN;
>> - writel(c, &usart->tx_dr);
>> + writel(c, base + TDR_OFFSET(stm32f4));
>> return 0;
>> }
>> static int stm32_serial_pending(struct udevice *dev, bool input)
>> {
>> - struct stm32x7_serial_platdata *plat = dev->platdata;
>> - struct stm32_usart *const usart = plat->base;
>> + struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
>> + bool stm32f4 = plat->uart_info->stm32f4;
>> + fdt_addr_t base = plat->base;
>> if (input)
>> - return readl(&usart->sr) & USART_SR_FLAG_RXNE ? 1 : 0;
>> + return readl(base + ISR_OFFSET(stm32f4)) &
>> + USART_SR_FLAG_RXNE ? 1 : 0;
>> else
>> - return readl(&usart->sr) & USART_SR_FLAG_TXE ? 0 : 1;
>> + return readl(base + ISR_OFFSET(stm32f4)) &
>> + USART_SR_FLAG_TXE ? 0 : 1;
>> }
>> static