From 86e3d523622a3474a35bfd1f0ceea577942da0de Mon Sep 17 00:00:00 2001 From: Rajkumar Ayyasamy Date: Wed, 8 Apr 2020 22:42:25 +0530 Subject: [PATCH] ipq6018: add UART clock settings Change-Id: Ifb80b67e961ae2cde93bc5709330c5df932d0b4b Signed-off-by: Rajkumar Ayyasamy --- arch/arm/dts/ipq6018-soc.dtsi | 3 + arch/arm/include/asm/arch-ipq6018/clk.h | 40 +++++++++ arch/arm/include/asm/arch-qca-common/uart.h | 1 + board/qca/arm/ipq6018/clock.c | 65 ++++++++++++++ board/qca/arm/ipq6018/ipq6018.c | 98 +++------------------ board/qca/arm/ipq6018/ipq6018.h | 26 ------ drivers/serial/qca_uart.c | 3 + 7 files changed, 124 insertions(+), 112 deletions(-) diff --git a/arch/arm/dts/ipq6018-soc.dtsi b/arch/arm/dts/ipq6018-soc.dtsi index f19906b586..801b217223 100644 --- a/arch/arm/dts/ipq6018-soc.dtsi +++ b/arch/arm/dts/ipq6018-soc.dtsi @@ -22,6 +22,9 @@ reg = <0x78B1000 0x200>; id = <4>; bit_rate = <0xff>; + m_value = <36>; + n_value = <15625>; + d_value = <15625>; serial_gpio { gpio1 { gpio = <44>; diff --git a/arch/arm/include/asm/arch-ipq6018/clk.h b/arch/arm/include/asm/arch-ipq6018/clk.h index 5d545d4bce..e33a06481c 100644 --- a/arch/arm/include/asm/arch-ipq6018/clk.h +++ b/arch/arm/include/asm/arch-ipq6018/clk.h @@ -14,6 +14,8 @@ #ifndef IPQ6018_CLK_H #define IPQ6018_CLK_H +#include + /* I2C clocks configuration */ #ifdef CONFIG_IPQ6018_I2C @@ -31,4 +33,42 @@ void i2c_clock_config(void); #endif +#define GCC_BLSP1_UART1_BCR 0x1802038 +#define GCC_BLSP1_UART2_BCR 0x1803028 +#define GCC_BLSP1_UART3_BCR 0x1804028 +#define GCC_BLSP1_UART4_BCR 0x1805028 +#define GCC_BLSP1_UART5_BCR 0x1806028 +#define GCC_BLSP1_UART6_BCR 0x1807028 + +#define GCC_BLSP1_UART_BCR(id) ((id < 1) ? \ + (GCC_BLSP1_UART1_BCR):\ + (GCC_BLSP1_UART1_BCR + (0x1000 * id) - 0x10)) + +#define GCC_BLSP1_UART_APPS_CBCR(id) (GCC_BLSP1_UART_BCR(id) + 0x04) +#define GCC_BLSP1_UART_APPS_CMD_RCGR(id) (GCC_BLSP1_UART_BCR(id) + 0x0C) +#define GCC_BLSP1_UART_APPS_CFG_RCGR(id) (GCC_BLSP1_UART_BCR(id) + 0x10) +#define GCC_BLSP1_UART_APPS_M(id) (GCC_BLSP1_UART_BCR(id) + 0x14) +#define GCC_BLSP1_UART_APPS_N(id) (GCC_BLSP1_UART_BCR(id) + 0x18) +#define GCC_BLSP1_UART_APPS_D(id) (GCC_BLSP1_UART_BCR(id) + 0x1C) + +#define GCC_UART_CFG_RCGR_MODE_MASK 0x3000 +#define GCC_UART_CFG_RCGR_SRCSEL_MASK 0x0700 +#define GCC_UART_CFG_RCGR_SRCDIV_MASK 0x001F + +#define GCC_UART_CFG_RCGR_MODE_SHIFT 12 +#define GCC_UART_CFG_RCGR_SRCSEL_SHIFT 8 +#define GCC_UART_CFG_RCGR_SRCDIV_SHIFT 0 + +#define UART_RCGR_SRC_SEL 0x1 +#define UART_RCGR_SRC_DIV 0x0 +#define UART_RCGR_MODE 0x2 +#define UART_CMD_RCGR_UPDATE 0x1 +#define UART_CBCR_CLK_ENABLE 0x1 + +#define NOT_2D(two_d) (~two_d) +#define NOT_N_MINUS_M(n,m) (~(n - m)) +#define CLOCK_UPDATE_TIMEOUT_US 1000 + +int uart_clock_config(struct ipq_serial_platdata *plat); + #endif /*IPQ6018_CLK_H*/ diff --git a/arch/arm/include/asm/arch-qca-common/uart.h b/arch/arm/include/asm/arch-qca-common/uart.h index f1c6474acd..cf9e839f6e 100644 --- a/arch/arm/include/asm/arch-qca-common/uart.h +++ b/arch/arm/include/asm/arch-qca-common/uart.h @@ -88,6 +88,7 @@ struct ipq_serial_platdata { int m_value; int n_value; int d_value; + int gpio_node; }; diff --git a/board/qca/arm/ipq6018/clock.c b/board/qca/arm/ipq6018/clock.c index 92beb069e5..71497fd7b0 100644 --- a/board/qca/arm/ipq6018/clock.c +++ b/board/qca/arm/ipq6018/clock.c @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef CONFIG_IPQ6018_I2C void i2c_clock_config(void) @@ -34,3 +35,67 @@ void i2c_clock_config(void) } #endif +static void uart_configure_mux(u8 id) +{ + unsigned long cfg_rcgr; + + cfg_rcgr = readl(GCC_BLSP1_UART_APPS_CFG_RCGR(id)); + /* Clear mode, src sel, src div */ + cfg_rcgr &= ~(GCC_UART_CFG_RCGR_MODE_MASK | + GCC_UART_CFG_RCGR_SRCSEL_MASK | + GCC_UART_CFG_RCGR_SRCDIV_MASK); + + cfg_rcgr |= ((UART_RCGR_SRC_SEL << GCC_UART_CFG_RCGR_SRCSEL_SHIFT) + & GCC_UART_CFG_RCGR_SRCSEL_MASK); + + cfg_rcgr |= ((UART_RCGR_SRC_DIV << GCC_UART_CFG_RCGR_SRCDIV_SHIFT) + & GCC_UART_CFG_RCGR_SRCDIV_MASK); + + cfg_rcgr |= ((UART_RCGR_MODE << GCC_UART_CFG_RCGR_MODE_SHIFT) + & GCC_UART_CFG_RCGR_MODE_MASK); + + writel(cfg_rcgr, GCC_BLSP1_UART_APPS_CFG_RCGR(id)); +} + +static int uart_trigger_update(u8 id) +{ + unsigned long cmd_rcgr; + int timeout = 0; + + cmd_rcgr = readl(GCC_BLSP1_UART_APPS_CMD_RCGR(id)); + cmd_rcgr |= UART_CMD_RCGR_UPDATE; + writel(cmd_rcgr, GCC_BLSP1_UART_APPS_CMD_RCGR(id)); + + while (readl(GCC_BLSP1_UART_APPS_CMD_RCGR(id)) & UART_CMD_RCGR_UPDATE) { + if (timeout++ >= CLOCK_UPDATE_TIMEOUT_US) { + printf("Timeout waiting for UART clock update\n"); + return -ETIMEDOUT; + } + udelay(1); + } + cmd_rcgr = readl(GCC_BLSP1_UART_APPS_CMD_RCGR(id)); + return 0; +} + +int uart_clock_config(struct ipq_serial_platdata *plat) +{ + unsigned long cbcr_val; + int ret; + + uart_configure_mux(plat->port_id); + + writel(plat->m_value, GCC_BLSP1_UART_APPS_M(plat->port_id)); + writel(NOT_N_MINUS_M(plat->n_value, plat->m_value), + GCC_BLSP1_UART_APPS_N(plat->port_id)); + writel(NOT_2D(plat->d_value), GCC_BLSP1_UART_APPS_D(plat->port_id)); + + ret = uart_trigger_update(plat->port_id); + if (ret) + return ret; + + cbcr_val = readl(GCC_BLSP1_UART_APPS_CBCR(plat->port_id)); + cbcr_val |= UART_CBCR_CLK_ENABLE; + writel(cbcr_val, GCC_BLSP1_UART_APPS_CBCR(plat->port_id)); + return 0; +} + diff --git a/board/qca/arm/ipq6018/ipq6018.c b/board/qca/arm/ipq6018/ipq6018.c index bea8351f41..9323a5520d 100644 --- a/board/qca/arm/ipq6018/ipq6018.c +++ b/board/qca/arm/ipq6018/ipq6018.c @@ -109,99 +109,25 @@ struct dumpinfo_t dumpinfo_s[] = { int dump_entries_s = ARRAY_SIZE(dumpinfo_s); u32 *tz_wonce = (u32 *)CONFIG_IPQ6018_TZ_WONCE_4_ADDR; - -void uart2_configure_mux(void) -{ - unsigned long cfg_rcgr; - - cfg_rcgr = readl(GCC_BLSP1_UART2_APPS_CFG_RCGR); - /* Clear mode, src sel, src div */ - cfg_rcgr &= ~(GCC_UART_CFG_RCGR_MODE_MASK | - GCC_UART_CFG_RCGR_SRCSEL_MASK | - GCC_UART_CFG_RCGR_SRCDIV_MASK); - - cfg_rcgr |= ((UART2_RCGR_SRC_SEL << GCC_UART_CFG_RCGR_SRCSEL_SHIFT) - & GCC_UART_CFG_RCGR_SRCSEL_MASK); - - cfg_rcgr |= ((UART2_RCGR_SRC_DIV << GCC_UART_CFG_RCGR_SRCDIV_SHIFT) - & GCC_UART_CFG_RCGR_SRCDIV_MASK); - - cfg_rcgr |= ((UART2_RCGR_MODE << GCC_UART_CFG_RCGR_MODE_SHIFT) - & GCC_UART_CFG_RCGR_MODE_MASK); - - writel(cfg_rcgr, GCC_BLSP1_UART2_APPS_CFG_RCGR); -} - -void uart2_set_rate_mnd(unsigned int m, - unsigned int n, unsigned int two_d) -{ - writel(m, GCC_BLSP1_UART2_APPS_M); - writel(NOT_N_MINUS_M(n, m), GCC_BLSP1_UART2_APPS_N); - writel(NOT_2D(two_d), GCC_BLSP1_UART2_APPS_D); -} - -int uart2_trigger_update(void) -{ - unsigned long cmd_rcgr; - int timeout = 0; - - cmd_rcgr = readl(GCC_BLSP1_UART2_APPS_CMD_RCGR); - cmd_rcgr |= UART2_CMD_RCGR_UPDATE; - writel(cmd_rcgr, GCC_BLSP1_UART2_APPS_CMD_RCGR); - - while (readl(GCC_BLSP1_UART2_APPS_CMD_RCGR) & UART2_CMD_RCGR_UPDATE) { - if (timeout++ >= CLOCK_UPDATE_TIMEOUT_US) { - printf("Timeout waiting for UART2 clock update\n"); - return -ETIMEDOUT; - } - udelay(1); - } - cmd_rcgr = readl(GCC_BLSP1_UART2_APPS_CMD_RCGR); - return 0; -} - -void uart2_toggle_clock(void) -{ - unsigned long cbcr_val; - - cbcr_val = readl(GCC_BLSP1_UART2_APPS_CBCR); - cbcr_val |= UART2_CBCR_CLK_ENABLE; - writel(cbcr_val, GCC_BLSP1_UART2_APPS_CBCR); -} - -void uart2_clock_config(unsigned int m, - unsigned int n, unsigned int two_d) -{ - uart2_configure_mux(); - uart2_set_rate_mnd(m, n, two_d); - uart2_trigger_update(); - uart2_toggle_clock(); -} +#define BLSP1_UART0_BASE 0x078AF000 +#define UART_PORT_ID(reg) ((reg - BLSP1_UART0_BASE) / 0x1000) void qca_serial_init(struct ipq_serial_platdata *plat) { - int node, uart2_node; + int ret; - writel(1, GCC_BLSP1_UART1_APPS_CBCR); - - node = fdt_path_offset(gd->fdt_blob, "/serial@78B1000/serial_gpio"); - if (node < 0) { - printf("Could not find serial_gpio node\n"); + if (plat->gpio_node < 0) { + printf("serial_init: unable to find gpio node \n"); return; } - if (plat->port_id == 1) { - uart2_node = fdt_path_offset(gd->fdt_blob, "uart2"); - if (uart2_node < 0) { - printf("Could not find uart2 node\n"); - return; - } - node = fdt_subnode_offset(gd->fdt_blob, - uart2_node, "serial_gpio"); - uart2_clock_config(plat->m_value, plat->n_value, plat->d_value); - writel(1, GCC_BLSP1_UART2_APPS_CBCR); - } - qca_gpio_init(node); + qca_gpio_init(plat->gpio_node); + plat->port_id = UART_PORT_ID(plat->reg_base); + ret = uart_clock_config(plat); + if (ret) + printf("UART clock config failed %d \n", ret); + + return; } int do_pmic_reset() diff --git a/board/qca/arm/ipq6018/ipq6018.h b/board/qca/arm/ipq6018/ipq6018.h index 85cb3f7362..c02fb9bbfa 100644 --- a/board/qca/arm/ipq6018/ipq6018.h +++ b/board/qca/arm/ipq6018/ipq6018.h @@ -59,35 +59,9 @@ #define SDCC1_N_VAL 0xFC #define SDCC1_D_VAL 0xFD -#define GCC_BLSP1_UART1_APPS_CBCR 0x0180203c #define GCC_SDCC1_BCR 0x01842000 #define GCC_SDCC1_AHB_CBCR 0x0184201C -#define GCC_BLSP1_UART2_APPS_CFG_RCGR 0x01803038 -#define GCC_BLSP1_UART2_APPS_M 0x0180303C -#define GCC_BLSP1_UART2_APPS_N 0x01803040 -#define GCC_BLSP1_UART2_APPS_D 0x01803044 -#define GCC_BLSP1_UART2_APPS_CMD_RCGR 0x01803034 -#define GCC_BLSP1_UART2_APPS_CBCR 0x0180302C - -#define GCC_UART_CFG_RCGR_MODE_MASK 0x3000 -#define GCC_UART_CFG_RCGR_SRCSEL_MASK 0x0700 -#define GCC_UART_CFG_RCGR_SRCDIV_MASK 0x001F - -#define GCC_UART_CFG_RCGR_MODE_SHIFT 12 -#define GCC_UART_CFG_RCGR_SRCSEL_SHIFT 8 -#define GCC_UART_CFG_RCGR_SRCDIV_SHIFT 0 - -#define UART2_RCGR_SRC_SEL 0x1 -#define UART2_RCGR_SRC_DIV 0x0 -#define UART2_RCGR_MODE 0x2 -#define UART2_CMD_RCGR_UPDATE 0x1 -#define UART2_CBCR_CLK_ENABLE 0x1 - -#define NOT_2D(two_d) (~two_d) -#define NOT_N_MINUS_M(n,m) (~(n - m)) -#define CLOCK_UPDATE_TIMEOUT_US 1000 - #define CLOCK_UPDATE_TIMEOUT_US 1000 #define KERNEL_AUTH_CMD 0x1E #define SCM_CMD_SEC_AUTH 0x1F diff --git a/drivers/serial/qca_uart.c b/drivers/serial/qca_uart.c index 49fc06605b..77acd785a0 100644 --- a/drivers/serial/qca_uart.c +++ b/drivers/serial/qca_uart.c @@ -453,6 +453,8 @@ static int ipq_serial_ofdata_to_platdata(struct udevice *dev) plat->n_value = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "n_value", -1); plat->d_value = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "d_value", -1); + plat->gpio_node = fdt_subnode_offset(gd->fdt_blob, dev->of_offset, "serial_gpio"); + return 0; } @@ -559,6 +561,7 @@ static void do_uart_start(void) uart2.n_value = fdtdec_get_int(gd->fdt_blob, node, "n_value", -1); uart2.d_value = fdtdec_get_int(gd->fdt_blob, node, "d_value", -1); + uart2.gpio_node = fdt_subnode_offset(gd->fdt_blob, node, "serial_gpio"); ipq_serial_init(&uart2, uart2.reg_base); }