On Wed, Feb 05, 2020 at 06:27:25PM +0100, Adrian Schmutzler wrote:
> Hi,
> 
> > -----Original Message-----
> > From: openwrt-devel [mailto:[email protected]] On
> > Behalf Of Daniel Golle
> > Sent: Mittwoch, 5. Februar 2020 16:19
> > To: [email protected]
> > Cc: Gerhard Bertelsmann <[email protected]>; Adrian Schmutzler
> > <[email protected]>; Piotr Dymacz <[email protected]>
> > 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 <[email protected]>
> > Signed-off-by: Daniel Golle <[email protected]>
> > ---
> >  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@18500000 {
> 
> What does the "hs" actually stand for?

In the AR9344 datasheet this UART is referred to as 'high speed UART'
while the ns16550-compatible one is reffered to as 'low speed UART'.

> 
> > +                           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?

No. It slipped in by accident.

> 
> Best
> 
> Adrian
> 
> >             nand: nand@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
> > [email protected]
> > https://lists.openwrt.org/mailman/listinfo/openwrt-devel
> 

_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to