Author: mmel
Date: Sat Apr 25 09:17:49 2020
New Revision: 360293
URL: https://svnweb.freebsd.org/changeset/base/360293

Log:
  Reorder initialization steps for given pin.
  If pin is switched from fixed function to GPIO, it should have prepared
  direction, pull-up/down and default value before function gets switched.
  Otherwise we may produce unwanted glitch on output pin.
  Right order of drive strength settings is questionable, but I think that
  is slightly safer to do it also before function switch.
  
  This fixes serial port corruption observed after DT 5.6 import.
  
  MFC after:    1 week

Modified:
  head/sys/arm64/rockchip/rk_pinctrl.c

Modified: head/sys/arm64/rockchip/rk_pinctrl.c
==============================================================================
--- head/sys/arm64/rockchip/rk_pinctrl.c        Sat Apr 25 09:06:11 2020        
(r360292)
+++ head/sys/arm64/rockchip/rk_pinctrl.c        Sat Apr 25 09:17:49 2020        
(r360293)
@@ -932,7 +932,28 @@ rk_pinctrl_configure_pin(struct rk_pinctrl_softc *sc, 
        /* Find syscon */
        syscon = sc->conf->get_syscon(sc, bank);
 
-       /* Parse pin function */
+       /* Setup GPIO properties first */
+       rv = rk_pinctrl_handle_io(sc, pin_conf, bank, pin);
+
+       /* Then pin pull-up/down */
+       bias = sc->conf->parse_bias(pin_conf, bank);
+       if (bias >= 0) {
+               reg = sc->conf->get_pd_offset(sc, bank);
+               reg += bank * 0x10 + ((pin / 8) * 0x4);
+               bit = (pin % 8) * 2;
+               mask = (0x3 << bit);
+               SYSCON_MODIFY_4(syscon, reg, mask, bias << bit | (mask << 16));
+       }
+
+       /* Then drive strength */
+       rv = rk_pinctrl_parse_drive(sc, pin_conf, bank, subbank, &drive, &reg);
+       if (rv == 0) {
+               bit = (pin % 8) * 2;
+               mask = (0x3 << bit);
+               SYSCON_MODIFY_4(syscon, reg, mask, drive << bit | (mask << 16));
+       }
+
+       /* Finally set the pin function */
        reg = sc->conf->iomux_conf[i].offset;
        switch (sc->conf->iomux_conf[i].nbits) {
        case 4:
@@ -966,28 +987,6 @@ rk_pinctrl_configure_pin(struct rk_pinctrl_softc *sc, 
         * without hi-word write mask.
         */
        SYSCON_MODIFY_4(syscon, reg, mask, function << bit | (mask << 16));
-
-       /* Pull-Up/Down */
-       bias = sc->conf->parse_bias(pin_conf, bank);
-       if (bias >= 0) {
-               reg = sc->conf->get_pd_offset(sc, bank);
-
-               reg += bank * 0x10 + ((pin / 8) * 0x4);
-               bit = (pin % 8) * 2;
-               mask = (0x3 << bit);
-               SYSCON_MODIFY_4(syscon, reg, mask, bias << bit | (mask << 16));
-       }
-
-       /* Drive Strength */
-       rv = rk_pinctrl_parse_drive(sc, pin_conf, bank, subbank, &drive, &reg);
-       if (rv == 0) {
-               bit = (pin % 8) * 2;
-               mask = (0x3 << bit);
-               SYSCON_MODIFY_4(syscon, reg, mask, drive << bit | (mask << 16));
-       }
-
-       /* Input/Outpot + default level */
-       rv = rk_pinctrl_handle_io(sc, pin_conf, bank, pin);
 }
 
 static int
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to