[OpenWrt-Devel] [PATCH 1/3] ath79: add support for Atheros AR934x HS UART
Adrian Schmutzler
mail at adrianschmutzler.de
Wed Feb 5 12:27:25 EST 2020
Hi,
> -----Original Message-----
> From: openwrt-devel [mailto:openwrt-devel-bounces at lists.openwrt.org] On
> Behalf Of Daniel Golle
> Sent: Mittwoch, 5. Februar 2020 16:19
> To: openwrt-devel at lists.openwrt.org
> Cc: Gerhard Bertelsmann <info at gerhard-bertelsmann.de>; Adrian Schmutzler
> <mail at adrianschmutzler.de>; Piotr Dymacz <pepe2k at gmail.com>
> Subject: [OpenWrt-Devel] [PATCH 1/3] ath79: add support for Atheros AR934x HS
> UART
>
> AR934x chips also got the 'old' qca,ar9330-uart in addition to the
> 'new' ns16550a compatible one. Add support for UART1 clock selector as
> well as device-tree bindings in ar934x.dtsi to make use of that uart.
> Diff'ing the drivers showed that the only difference is that AR934x
> requires setting UART1_CS_TX_READY_ORIDE and UART1_CS_RX_READY_ORIDE
> registers which seems to be unneeded on AR933x (probably because it's
> already set by the bootloader which on AR934x typically uses the
> NS16550-compatible UART and hence doesn't touch those registers).
> Without those registers set, the UART will not function without
> hardware flow-control being enabled (which is not an option as
> RTS/CTS pins may not be assigned).
>
> Reported-by: Piotr Dymacz <pepe2k at gmail.com>
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> ---
> target/linux/ath79/dts/ar934x.dtsi | 17 +++
> ...S-ath79-export-UART1-reference-clock.patch | 52 +++++++
> ...40-tty-serial-ar933x-uart-add-ar934x.patch | 128 ++++++++++++++++++
> 3 files changed, 197 insertions(+)
> create mode 100644 target/linux/ath79/patches-4.19/0039-MIPS-ath79-export-
> UART1-reference-clock.patch
> create mode 100644 target/linux/ath79/patches-4.19/0040-tty-serial-ar933x-
> uart-add-ar934x.patch
>
> diff --git a/target/linux/ath79/dts/ar934x.dtsi
> b/target/linux/ath79/dts/ar934x.dtsi
> index 8cd0b4e086..d90d823884 100644
> --- a/target/linux/ath79/dts/ar934x.dtsi
> +++ b/target/linux/ath79/dts/ar934x.dtsi
> @@ -133,8 +133,25 @@
>
> #reset-cells = <1>;
> };
> +
> + hs_uart: uart at 18500000 {
What does the "hs" actually stand for?
> + compatible = "qca,ar9341-uart";
> + reg = <0x18500000 0x14>;
> +
> + interrupts = <6>;
> + interrupt-parent = <&miscintc>;
> +
> + clocks = <&pll ATH79_CLK_UART1>;
> + clock-names = "uart";
> +
> + resets = <&rst 17>;
> + reset-names = "uart";
> +
> + status = "disabled";
> + };
> };
>
> +
Any reason for this additional empty line?
Best
Adrian
> nand: nand at 1b000200 {
> compatible = "qca,ar934x-nand";
> reg = <0x1b000200 0xb8>;
> diff --git a/target/linux/ath79/patches-4.19/0039-MIPS-ath79-export-UART1-
> reference-clock.patch b/target/linux/ath79/patches-4.19/0039-MIPS-ath79-
> export-UART1-reference-clock.patch
> new file mode 100644
> index 0000000000..8656fafe0e
> --- /dev/null
> +++ b/target/linux/ath79/patches-4.19/0039-MIPS-ath79-export-UART1-
> reference-clock.patch
> @@ -0,0 +1,52 @@
> +--- a/arch/mips/ath79/clock.c
> ++++ b/arch/mips/ath79/clock.c
> +@@ -42,6 +42,7 @@ static const char * const clk_names[ATH7
> + [ATH79_CLK_AHB] = "ahb",
> + [ATH79_CLK_REF] = "ref",
> + [ATH79_CLK_MDIO] = "mdio",
> ++ [ATH79_CLK_UART1] = "uart1",
> + };
> +
> + static const char * __init ath79_clk_name(int type)
> +@@ -346,6 +347,9 @@ static void __init ar934x_clocks_init(vo
> + if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL)
> + ath79_set_clk(ATH79_CLK_MDIO, 100 * 1000 * 1000);
> +
> ++ if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_UART1_CLK_SEL)
> ++ ath79_set_clk(ATH79_CLK_UART1, 100 * 1000 * 1000);
> ++
> + iounmap(dpll_base);
> + }
> +
> +@@ -651,6 +655,9 @@ static void __init ath79_clocks_init_dt(
> + if (!clks[ATH79_CLK_MDIO])
> + clks[ATH79_CLK_MDIO] = clks[ATH79_CLK_REF];
> +
> ++ if (!clks[ATH79_CLK_UART1])
> ++ clks[ATH79_CLK_UART1] = clks[ATH79_CLK_REF];
> ++
> + if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) {
> + pr_err("%pOF: could not register clk provider\n", np);
> + goto err_iounmap;
> +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
> ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
> +@@ -351,6 +351,7 @@
> + #define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL
> BIT(24)
> +
> + #define AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL BIT(6)
> ++#define AR934X_PLL_SWITCH_CLOCK_CONTROL_UART1_CLK_SEL BIT(7)
> +
> + #define QCA953X_PLL_CPU_CONFIG_REG 0x00
> + #define QCA953X_PLL_DDR_CONFIG_REG 0x04
> +--- a/include/dt-bindings/clock/ath79-clk.h
> ++++ b/include/dt-bindings/clock/ath79-clk.h
> +@@ -15,7 +15,8 @@
> + #define ATH79_CLK_AHB 2
> + #define ATH79_CLK_REF 3
> + #define ATH79_CLK_MDIO 4
> ++#define ATH79_CLK_UART1 5
> +
> +-#define ATH79_CLK_END 5
> ++#define ATH79_CLK_END 6
> +
> + #endif /* __DT_BINDINGS_ATH79_CLK_H */
> diff --git a/target/linux/ath79/patches-4.19/0040-tty-serial-ar933x-uart-add-
> ar934x.patch
b/target/linux/ath79/patches-4.19/0040-tty-serial-ar933x-uart-add-
> ar934x.patch
> new file mode 100644
> index 0000000000..f8f0ffbea1
> --- /dev/null
> +++ b/target/linux/ath79/patches-4.19/0040-tty-serial-ar933x-uart-add-
> ar934x.patch
> @@ -0,0 +1,128 @@
> +Index: linux-4.19.98/drivers/tty/serial/ar933x_uart.c
> +=============================================================
> ======
> +--- linux-4.19.98.orig/drivers/tty/serial/ar933x_uart.c
> ++++ linux-4.19.98/drivers/tty/serial/ar933x_uart.c
> +@@ -39,6 +39,9 @@
> +
> + #define AR933X_DUMMY_STATUS_RD 0x01
> +
> ++#define UART_IS_AR9330 0
> ++#define UART_IS_AR9341 1
> ++
> + static struct uart_driver ar933x_uart_driver;
> +
> + struct ar933x_uart_port {
> +@@ -46,6 +49,7 @@ struct ar933x_uart_port {
> + unsigned int ier; /* shadow Interrupt Enable Register */
> + unsigned int min_baud;
> + unsigned int max_baud;
> ++ unsigned int subtype;
> + struct clk *clk;
> + };
> +
> +@@ -286,6 +290,15 @@ static void ar933x_uart_set_termios(stru
> + ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
> + AR933X_UART_CS_HOST_INT_EN);
> +
> ++ if (up->subtype == UART_IS_AR9341) {
> ++ /* enable TX ready overide */
> ++ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
> ++ AR933X_UART_CS_TX_READY_ORIDE);
> ++ /* enable RX ready overide */
> ++ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
> ++ AR933X_UART_CS_RX_READY_ORIDE);
> ++ }
> ++
> + /* reenable the UART */
> + ar933x_uart_rmw(up, AR933X_UART_CS_REG,
> + AR933X_UART_CS_IF_MODE_M <<
> AR933X_UART_CS_IF_MODE_S,
> +@@ -418,6 +431,12 @@ static int ar933x_uart_startup(struct ua
> + ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
> + AR933X_UART_CS_HOST_INT_EN);
> +
> ++ if (up->subtype == UART_IS_AR9341) {
> ++ /* enable TX ready overide */
> ++ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
> ++ AR933X_UART_CS_TX_READY_ORIDE);
> ++ }
> ++
> + /* Enable RX interrupts */
> + up->ier = AR933X_UART_INT_RX_VALID;
> + ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
> +@@ -445,7 +464,11 @@ static void ar933x_uart_shutdown(struct
> +
> + static const char *ar933x_uart_type(struct uart_port *port)
> + {
> +- return (port->type == PORT_AR933X) ? "AR933X UART" : NULL;
> ++ struct ar933x_uart_port *up =
> ++ container_of(port, struct ar933x_uart_port, port);
> ++
> ++ return (port->type == PORT_AR933X) ?
> ++ ((up->subtype == UART_IS_AR9341) ? "AR934X high-speed UART"
> : "AR933X UART") : NULL;
> + }
> +
> + static void ar933x_uart_release_port(struct uart_port *port)
> +@@ -610,6 +633,15 @@ static struct uart_driver ar933x_uart_dr
> + .cons = NULL, /* filled in runtime */
> + };
> +
> ++#ifdef CONFIG_OF
> ++static const struct of_device_id ar933x_uart_of_ids[] = {
> ++ { .compatible = "qca,ar9330-uart", .data = (const void *)UART_IS_AR9330
> },
> ++ { .compatible = "qca,ar9341-uart", .data = (const void *)UART_IS_AR9341
> },
> ++ {},
> ++};
> ++MODULE_DEVICE_TABLE(of, ar933x_uart_of_ids);
> ++#endif
> ++
> + static int ar933x_uart_probe(struct platform_device *pdev)
> + {
> + struct ar933x_uart_port *up;
> +@@ -617,9 +649,12 @@ static int ar933x_uart_probe(struct plat
> + struct resource *mem_res;
> + struct resource *irq_res;
> + struct device_node *np;
> ++ const struct of_device_id *match;
> ++
> + unsigned int baud;
> + int id;
> + int ret;
> ++ int subtype = UART_IS_AR9330;
> +
> + np = pdev->dev.of_node;
> + if (IS_ENABLED(CONFIG_OF) && np) {
> +@@ -629,6 +664,10 @@ static int ar933x_uart_probe(struct plat
> + id);
> + return id;
> + }
> ++ match = of_match_node(ar933x_uart_of_ids, np);
> ++ if (match)
> ++ subtype = (int)match->data;
> ++
> + } else {
> + id = pdev->id;
> + if (id == -1)
> +@@ -649,6 +688,8 @@ static int ar933x_uart_probe(struct plat
> + if (!up)
> + return -ENOMEM;
> +
> ++ up->subtype = subtype;
> ++
> + up->clk = devm_clk_get(&pdev->dev, "uart");
> + if (IS_ERR(up->clk)) {
> + dev_err(&pdev->dev, "unable to get UART clock\n");
> +@@ -719,14 +760,6 @@ static int ar933x_uart_remove(struct pla
> + return 0;
> + }
> +
> +-#ifdef CONFIG_OF
> +-static const struct of_device_id ar933x_uart_of_ids[] = {
> +- { .compatible = "qca,ar9330-uart" },
> +- {},
> +-};
> +-MODULE_DEVICE_TABLE(of, ar933x_uart_of_ids);
> +-#endif
> +-
> + static struct platform_driver ar933x_uart_platform_driver = {
> + .probe = ar933x_uart_probe,
> + .remove = ar933x_uart_remove,
> --
> 2.25.0
>
>
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel at lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel
More information about the openwrt-devel
mailing list