> Date: Tue, 06 Feb 2024 22:37:50 +0900
> From: SASANO Takayoshi <u...@mx5.nisiq.net>
> 
> Hello,
> 
> I am working for H616 since OrangePi Zero2...
> 
> Here's the diff. sximmc.c is reconstructed.

Hi,


> Index: ehci_fdt.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/fdt/ehci_fdt.c,v
> diff -u -p -r1.11 ehci_fdt.c
> --- ehci_fdt.c        26 Jan 2024 17:11:50 -0000      1.11
> +++ ehci_fdt.c        6 Feb 2024 12:48:22 -0000
> @@ -207,6 +207,7 @@ struct ehci_phy ehci_phys[] = {
>       { "allwinner,sun8i-v3s-usb-phy", sun4i_phy_init },
>       { "allwinner,sun20i-d1-usb-phy", sun4i_phy_init },
>       { "allwinner,sun50i-h6-usb-phy", sun4i_phy_init },
> +     { "allwinner,sun50i-h616-usb-phy", sun4i_phy_init },
>       { "allwinner,sun50i-a64-usb-phy", sun4i_phy_init },
>       { "allwinner,sun9i-a80-usb-phy", sun9i_phy_init },
>  };
> @@ -287,6 +288,62 @@ ehci_init_phys(struct ehci_fdt_softc *sc
>  #define  SUNXI_AHB_INCR16    (1 << 11)
>  
>  void
> +sun50i_h616_phy2_init(struct ehci_fdt_softc *sc, int node)
> +{
> +     int len, idx;
> +     uint32_t *reg, val;
> +     bus_size_t size;
> +     bus_space_handle_t ioh;
> +
> +     /*
> +      * to access USB2-PHY register, get address from "reg" property of
> +      * current "allwinner,...-usb-phy" node
> +      */
> +     len = OF_getproplen(node, "reg");
> +     if (len <= 0)
> +             goto out;
> +
> +     reg = malloc(len, M_TEMP, M_WAITOK);
> +     OF_getpropintarray(node, "reg", reg, len);
> +
> +     idx = OF_getindex(node, "pmu2", "reg-names");
> +     if (idx < 0 || (idx + 1) > (len / (sizeof(uint32_t) * 2))) {
> +             printf(": no phy2 register\n");
> +             goto free;
> +     }
> +
> +     /* convert "reg-names" index to "reg" (address-size pair) index */
> +     idx *= 2;
> +
> +     size = reg[idx + 1];
> +     if (bus_space_map(sc->sc.iot, reg[idx], size, 0, &ioh)) {
> +             printf(": can't map phy2 registers\n");
> +             goto free;
> +     }
> +
> +     clock_enable(node, "usb2_phy");
> +     reset_deassert(node, "usb2_reset");
> +     clock_enable(node, "pmu2_clk");
> +
> +     /*
> +      * address is offset from "pmu2", not EHCI2 base address
> +      * (normally it points EHCI2 base address + 0x810)
> +      */
> +     val = bus_space_read_4(sc->sc.iot, ioh, 0x10);
> +     val &= ~(1 << 3);       /* clear SIDDQ */
> +     bus_space_write_4(sc->sc.iot, ioh, 0x10, val);
> +
> +     clock_disable(node, "pmu2_clk");
> +     /* "usb2_reset" and "usb2_phy" unchanged */
> +
> +     bus_space_unmap(sc->sc.iot, ioh, size);
> +free:
> +     free(reg, M_TEMP, len);
> +out:
> +     return;
> +}

This will be easier if we turn the Allwinner USB PHY code into a
proper driver, but it is fine for now.

> +
> +void
>  sun4i_phy_init(struct ehci_fdt_softc *sc, uint32_t *cells)
>  {
>       uint32_t vbus_supply;
> @@ -298,6 +355,11 @@ sun4i_phy_init(struct ehci_fdt_softc *sc
>       if (node == -1)
>               return;
>  
> +     /* Allwinner H616 needs to clear PHY2's SIDDQ flag */
> +     if (OF_is_compatible(node, "allwinner,sun50i-h616-usb-phy") &&
> +         cells[1] != 2)
> +             sun50i_h616_phy2_init(sc, node);
> +
>       val = bus_space_read_4(sc->sc.iot, sc->sc.ioh, SUNXI_HCI_ICR);
>       val |= SUNXI_AHB_INCR8 | SUNXI_AHB_INCR4;
>       val |= SUNXI_AHB_INCRX_ALIGN;
> @@ -318,6 +380,13 @@ sun4i_phy_init(struct ehci_fdt_softc *sc
>       } else if (OF_is_compatible(node, "allwinner,sun20i-d1-usb-phy")) {
>               val = bus_space_read_4(sc->sc.iot, sc->sc.ioh, 0x810);
>               val &= ~(1 << 3);
> +             bus_space_write_4(sc->sc.iot, sc->sc.ioh, 0x810, val);
> +     }
> +     if (OF_is_compatible(node, "allwinner,sun50i-h616-usb-phy") ||
> +         OF_is_compatible(node, "allwinner,sun50i-a83t-usb-phy")) {

There is no sun50i-a83t; you probably meant sun8i-a83t here, but I
don't think it is worth bothering about the A83T SoC, since it is
armv7 and pretty old.

> +             val = bus_space_read_4(sc->sc.iot, sc->sc.ioh, 0x810);
> +             val |= 1 << 5;          /* set VBUSVLDEXT */

The Linux driver sets this bit for Allwinner D1 too, so you can simply
merge this with the sun50i-d1 case.

> +             val &= ~(1 << 3);       /* clear SIDDQ */
>               bus_space_write_4(sc->sc.iot, sc->sc.ioh, 0x810, val);
>       }
>  

Reply via email to