diff --git a/sys/arm64/rockchip/rk_usb2phy.c b/sys/arm64/rockchip/rk_usb2phy.c --- a/sys/arm64/rockchip/rk_usb2phy.c +++ b/sys/arm64/rockchip/rk_usb2phy.c @@ -54,10 +54,13 @@ #include "clkdev_if.h" #include "syscon_if.h" -#define RK3399_GRF_USB20_PHY0_CON0 0x0 -#define RK3399_GRF_USB20_PHY0_CON1 0x4 -#define RK3399_GRF_USB20_PHY0_CON2 0x8 -#define RK3399_GRF_USB20_PHY0_CON3 0xC +#define USBPHY_USB2_GRF_CON0 0x0 +#define USBPHY_USB2_GRF_CON1 0x4 + +#define WRITEABLE_BITS_SHIFT 16 +#define WRITEABLE_BITS_MASK 0x3 +#define MODE_HOST_ENABLE 0x0 +#define MODE_HOST_DISABLE 0x2 struct rk_usb2phy_reg { uint32_t offset; @@ -72,6 +75,15 @@ struct rk_usb2phy_regs rk3399_regs = { .clk_ctl = { /* bit 4 put pll in suspend */ + .offset = 0xe450, + .enable_mask = 0x100000, + .disable_mask = 0x100010, + } +}; + +struct rk_usb2phy_regs rk3568_regs = { + .clk_ctl = { + .offset = 0x0008, .enable_mask = 0x100000, .disable_mask = 0x100010, } @@ -79,6 +91,7 @@ static struct ofw_compat_data compat_data[] = { { "rockchip,rk3399-usb2phy", (uintptr_t)&rk3399_regs }, + { "rockchip,rk3568-usb2phy", (uintptr_t)&rk3568_regs }, { NULL, 0 } }; @@ -106,9 +119,9 @@ rk_usb2phy_phynode_methods, sizeof(struct phynode_usb_sc), phynode_usb_class); -enum RK3399_USBPHY { - RK3399_USBPHY_HOST = 0, - RK3399_USBPHY_OTG, +enum RK_USBPHY { + RK_USBPHY_HOST = 0, + RK_USBPHY_OTG, }; static int @@ -116,15 +129,22 @@ { struct rk_usb2phy_softc *sc; device_t dev; - intptr_t phy; + uint32_t write_mask, write_val; int error; dev = phynode_get_device(phynode); - phy = phynode_get_id(phynode); sc = device_get_softc(dev); - if (phy != RK3399_USBPHY_HOST) + switch (sc->mode) { + case PHY_USB_MODE_HOST: + write_mask = WRITEABLE_BITS_MASK << WRITEABLE_BITS_SHIFT; + write_val = enable ? MODE_HOST_ENABLE : MODE_HOST_DISABLE; + break; + + case PHY_USB_MODE_OTG: + default: return (ERANGE); + } if (sc->phy_supply) { if (enable) @@ -138,6 +158,10 @@ } } + /* we have one PHY with two ports adjust both */ + SYSCON_WRITE_4(sc->grf, USBPHY_USB2_GRF_CON0, write_mask | write_val); + SYSCON_WRITE_4(sc->grf, USBPHY_USB2_GRF_CON1, write_mask | write_val); + return (0); fail: return (ENXIO); @@ -154,7 +178,7 @@ phy = phynode_get_id(phynode); sc = device_get_softc(dev); - if (phy != RK3399_USBPHY_HOST) + if (phy != RK_USBPHY_HOST) return (ERANGE); *mode = sc->mode; @@ -173,7 +197,7 @@ phy = phynode_get_id(phynode); sc = device_get_softc(dev); - if (phy != RK3399_USBPHY_HOST) + if (phy != RK_USBPHY_HOST) return (ERANGE); sc->mode = mode; @@ -259,7 +283,6 @@ struct clknode *clk; clk_t clk_parent; phandle_t node; - phandle_t regs[2]; int i, nclocks, ncells, error; node = ofw_bus_get_node(devsc->dev); @@ -304,8 +327,6 @@ sc->clkdev = device_get_parent(devsc->dev); sc->grf = devsc->grf; sc->regs = (struct rk_usb2phy_regs *)ofw_bus_search_compatible(devsc->dev, compat_data)->ocd_data; - OF_getencprop(node, "reg", regs, sizeof(regs)); - sc->regs->clk_ctl.offset = regs[0]; clknode_register(clkdom, clk); if (clkdom_finit(clkdom) != 0) { @@ -329,7 +350,7 @@ if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); - device_set_desc(dev, "Rockchip RK3399 USB2PHY"); + device_set_desc(dev, "Rockchip USB2PHY"); return (BUS_PROBE_DEFAULT); } @@ -346,9 +367,17 @@ sc->dev = dev; node = ofw_bus_get_node(dev); - if (syscon_get_handle_default(dev, &sc->grf) != 0) { - device_printf(dev, "Cannot get syscon handle\n"); - return (ENXIO); + if (OF_hasprop(node, "rockchip,usbgrf")) { + if (syscon_get_by_ofw_property(dev, node, "rockchip,usbgrf", + &sc->grf)) { + device_printf(dev, "Cannot get syscon handle\n"); + return (ENXIO); + } + } else { + if (syscon_get_handle_default(dev, &sc->grf)) { + device_printf(dev, "Cannot get syscon handle\n"); + return (ENXIO); + } } if (clk_get_by_ofw_name(dev, 0, "phyclk", &sc->clk) != 0) { @@ -380,7 +409,7 @@ } regulator_get_by_ofw_property(dev, host, "phy-supply", &sc->phy_supply); - phy_init.id = RK3399_USBPHY_HOST; + phy_init.id = RK_USBPHY_HOST; phy_init.ofw_node = host; phynode = phynode_create(dev, &rk_usb2phy_phynode_class, &phy_init); if (phynode == NULL) {