1*c3e25952SEmmanuel Vadot /*- 2*c3e25952SEmmanuel Vadot * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*c3e25952SEmmanuel Vadot * 4*c3e25952SEmmanuel Vadot * Copyright (c) 2019 Emmanuel Vadot <manu@FreeBSD.Org> 5*c3e25952SEmmanuel Vadot * 6*c3e25952SEmmanuel Vadot * Redistribution and use in source and binary forms, with or without 7*c3e25952SEmmanuel Vadot * modification, are permitted provided that the following conditions 8*c3e25952SEmmanuel Vadot * are met: 9*c3e25952SEmmanuel Vadot * 1. Redistributions of source code must retain the above copyright 10*c3e25952SEmmanuel Vadot * notice, this list of conditions and the following disclaimer. 11*c3e25952SEmmanuel Vadot * 2. Redistributions in binary form must reproduce the above copyright 12*c3e25952SEmmanuel Vadot * notice, this list of conditions and the following disclaimer in the 13*c3e25952SEmmanuel Vadot * documentation and/or other materials provided with the distribution. 14*c3e25952SEmmanuel Vadot * 15*c3e25952SEmmanuel Vadot * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*c3e25952SEmmanuel Vadot * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*c3e25952SEmmanuel Vadot * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*c3e25952SEmmanuel Vadot * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*c3e25952SEmmanuel Vadot * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*c3e25952SEmmanuel Vadot * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*c3e25952SEmmanuel Vadot * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*c3e25952SEmmanuel Vadot * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*c3e25952SEmmanuel Vadot * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*c3e25952SEmmanuel Vadot * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*c3e25952SEmmanuel Vadot * SUCH DAMAGE. 26*c3e25952SEmmanuel Vadot */ 27*c3e25952SEmmanuel Vadot 28*c3e25952SEmmanuel Vadot /* 29*c3e25952SEmmanuel Vadot * Rockchip USB2PHY 30*c3e25952SEmmanuel Vadot */ 31*c3e25952SEmmanuel Vadot 32*c3e25952SEmmanuel Vadot #include <sys/cdefs.h> 33*c3e25952SEmmanuel Vadot __FBSDID("$FreeBSD$"); 34*c3e25952SEmmanuel Vadot 35*c3e25952SEmmanuel Vadot #include <sys/param.h> 36*c3e25952SEmmanuel Vadot #include <sys/systm.h> 37*c3e25952SEmmanuel Vadot #include <sys/bus.h> 38*c3e25952SEmmanuel Vadot #include <sys/rman.h> 39*c3e25952SEmmanuel Vadot #include <sys/kernel.h> 40*c3e25952SEmmanuel Vadot #include <sys/module.h> 41*c3e25952SEmmanuel Vadot #include <sys/gpio.h> 42*c3e25952SEmmanuel Vadot #include <machine/bus.h> 43*c3e25952SEmmanuel Vadot 44*c3e25952SEmmanuel Vadot #include <dev/fdt/fdt_common.h> 45*c3e25952SEmmanuel Vadot #include <dev/ofw/ofw_bus.h> 46*c3e25952SEmmanuel Vadot #include <dev/ofw/ofw_bus_subr.h> 47*c3e25952SEmmanuel Vadot #include <dev/ofw/ofw_subr.h> 48*c3e25952SEmmanuel Vadot 49*c3e25952SEmmanuel Vadot #include <dev/extres/clk/clk.h> 50*c3e25952SEmmanuel Vadot #include <dev/extres/phy/phy_usb.h> 51*c3e25952SEmmanuel Vadot #include <dev/extres/regulator/regulator.h> 52*c3e25952SEmmanuel Vadot #include <dev/extres/syscon/syscon.h> 53*c3e25952SEmmanuel Vadot 54*c3e25952SEmmanuel Vadot #include "clkdev_if.h" 55*c3e25952SEmmanuel Vadot #include "syscon_if.h" 56*c3e25952SEmmanuel Vadot 57*c3e25952SEmmanuel Vadot #define RK3399_GRF_USB20_PHY0_CON0 0x0 58*c3e25952SEmmanuel Vadot #define RK3399_GRF_USB20_PHY0_CON1 0x4 59*c3e25952SEmmanuel Vadot #define RK3399_GRF_USB20_PHY0_CON2 0x8 60*c3e25952SEmmanuel Vadot #define RK3399_GRF_USB20_PHY0_CON3 0xC 61*c3e25952SEmmanuel Vadot 62*c3e25952SEmmanuel Vadot struct rk_usb2phy_reg { 63*c3e25952SEmmanuel Vadot uint32_t offset; 64*c3e25952SEmmanuel Vadot uint32_t enable_mask; 65*c3e25952SEmmanuel Vadot uint32_t disable_mask; 66*c3e25952SEmmanuel Vadot }; 67*c3e25952SEmmanuel Vadot 68*c3e25952SEmmanuel Vadot struct rk_usb2phy_regs { 69*c3e25952SEmmanuel Vadot struct rk_usb2phy_reg clk_ctl; 70*c3e25952SEmmanuel Vadot }; 71*c3e25952SEmmanuel Vadot 72*c3e25952SEmmanuel Vadot struct rk_usb2phy_regs rk3399_regs = { 73*c3e25952SEmmanuel Vadot .clk_ctl = { 74*c3e25952SEmmanuel Vadot /* bit 4 put pll in suspend */ 75*c3e25952SEmmanuel Vadot .enable_mask = 0x100000, 76*c3e25952SEmmanuel Vadot .disable_mask = 0x100010, 77*c3e25952SEmmanuel Vadot } 78*c3e25952SEmmanuel Vadot }; 79*c3e25952SEmmanuel Vadot 80*c3e25952SEmmanuel Vadot static struct ofw_compat_data compat_data[] = { 81*c3e25952SEmmanuel Vadot { "rockchip,rk3399-usb2phy", (uintptr_t)&rk3399_regs }, 82*c3e25952SEmmanuel Vadot { NULL, 0 } 83*c3e25952SEmmanuel Vadot }; 84*c3e25952SEmmanuel Vadot 85*c3e25952SEmmanuel Vadot struct rk_usb2phy_softc { 86*c3e25952SEmmanuel Vadot device_t dev; 87*c3e25952SEmmanuel Vadot struct syscon *grf; 88*c3e25952SEmmanuel Vadot regulator_t phy_supply; 89*c3e25952SEmmanuel Vadot clk_t clk; 90*c3e25952SEmmanuel Vadot }; 91*c3e25952SEmmanuel Vadot 92*c3e25952SEmmanuel Vadot /* Phy class and methods. */ 93*c3e25952SEmmanuel Vadot static int rk_usb2phy_enable(struct phynode *phynode, bool enable); 94*c3e25952SEmmanuel Vadot static phynode_method_t rk_usb2phy_phynode_methods[] = { 95*c3e25952SEmmanuel Vadot PHYNODEMETHOD(phynode_enable, rk_usb2phy_enable), 96*c3e25952SEmmanuel Vadot 97*c3e25952SEmmanuel Vadot PHYNODEMETHOD_END 98*c3e25952SEmmanuel Vadot }; 99*c3e25952SEmmanuel Vadot 100*c3e25952SEmmanuel Vadot DEFINE_CLASS_1(rk_usb2phy_phynode, rk_usb2phy_phynode_class, 101*c3e25952SEmmanuel Vadot rk_usb2phy_phynode_methods, 102*c3e25952SEmmanuel Vadot sizeof(struct phynode_usb_sc), phynode_usb_class); 103*c3e25952SEmmanuel Vadot 104*c3e25952SEmmanuel Vadot enum RK3399_USBPHY { 105*c3e25952SEmmanuel Vadot RK3399_USBPHY_HOST = 0, 106*c3e25952SEmmanuel Vadot RK3399_USBPHY_OTG, 107*c3e25952SEmmanuel Vadot }; 108*c3e25952SEmmanuel Vadot 109*c3e25952SEmmanuel Vadot static int 110*c3e25952SEmmanuel Vadot rk_usb2phy_enable(struct phynode *phynode, bool enable) 111*c3e25952SEmmanuel Vadot { 112*c3e25952SEmmanuel Vadot struct rk_usb2phy_softc *sc; 113*c3e25952SEmmanuel Vadot device_t dev; 114*c3e25952SEmmanuel Vadot intptr_t phy; 115*c3e25952SEmmanuel Vadot int error; 116*c3e25952SEmmanuel Vadot 117*c3e25952SEmmanuel Vadot dev = phynode_get_device(phynode); 118*c3e25952SEmmanuel Vadot phy = phynode_get_id(phynode); 119*c3e25952SEmmanuel Vadot sc = device_get_softc(dev); 120*c3e25952SEmmanuel Vadot 121*c3e25952SEmmanuel Vadot if (phy != RK3399_USBPHY_HOST) 122*c3e25952SEmmanuel Vadot return (ERANGE); 123*c3e25952SEmmanuel Vadot 124*c3e25952SEmmanuel Vadot if (sc->phy_supply) { 125*c3e25952SEmmanuel Vadot if (enable) 126*c3e25952SEmmanuel Vadot error = regulator_enable(sc->phy_supply); 127*c3e25952SEmmanuel Vadot else 128*c3e25952SEmmanuel Vadot error = regulator_disable(sc->phy_supply); 129*c3e25952SEmmanuel Vadot if (error != 0) { 130*c3e25952SEmmanuel Vadot device_printf(dev, "Cannot %sable the regulator\n", 131*c3e25952SEmmanuel Vadot enable ? "En" : "Dis"); 132*c3e25952SEmmanuel Vadot goto fail; 133*c3e25952SEmmanuel Vadot } 134*c3e25952SEmmanuel Vadot } 135*c3e25952SEmmanuel Vadot 136*c3e25952SEmmanuel Vadot return (0); 137*c3e25952SEmmanuel Vadot fail: 138*c3e25952SEmmanuel Vadot return (ENXIO); 139*c3e25952SEmmanuel Vadot } 140*c3e25952SEmmanuel Vadot 141*c3e25952SEmmanuel Vadot /* Clock class and method */ 142*c3e25952SEmmanuel Vadot struct rk_usb2phy_clk_sc { 143*c3e25952SEmmanuel Vadot device_t clkdev; 144*c3e25952SEmmanuel Vadot struct syscon *grf; 145*c3e25952SEmmanuel Vadot struct rk_usb2phy_regs *regs; 146*c3e25952SEmmanuel Vadot }; 147*c3e25952SEmmanuel Vadot 148*c3e25952SEmmanuel Vadot static int 149*c3e25952SEmmanuel Vadot rk_usb2phy_clk_init(struct clknode *clk, device_t dev) 150*c3e25952SEmmanuel Vadot { 151*c3e25952SEmmanuel Vadot 152*c3e25952SEmmanuel Vadot clknode_init_parent_idx(clk, 0); 153*c3e25952SEmmanuel Vadot return (0); 154*c3e25952SEmmanuel Vadot } 155*c3e25952SEmmanuel Vadot 156*c3e25952SEmmanuel Vadot static int 157*c3e25952SEmmanuel Vadot rk_usb2phy_clk_set_gate(struct clknode *clk, bool enable) 158*c3e25952SEmmanuel Vadot { 159*c3e25952SEmmanuel Vadot struct rk_usb2phy_clk_sc *sc; 160*c3e25952SEmmanuel Vadot 161*c3e25952SEmmanuel Vadot sc = clknode_get_softc(clk); 162*c3e25952SEmmanuel Vadot 163*c3e25952SEmmanuel Vadot if (enable) 164*c3e25952SEmmanuel Vadot SYSCON_WRITE_4(sc->grf, sc->regs->clk_ctl.offset, 165*c3e25952SEmmanuel Vadot sc->regs->clk_ctl.enable_mask); 166*c3e25952SEmmanuel Vadot else 167*c3e25952SEmmanuel Vadot SYSCON_WRITE_4(sc->grf, sc->regs->clk_ctl.offset, 168*c3e25952SEmmanuel Vadot sc->regs->clk_ctl.disable_mask); 169*c3e25952SEmmanuel Vadot return (0); 170*c3e25952SEmmanuel Vadot } 171*c3e25952SEmmanuel Vadot 172*c3e25952SEmmanuel Vadot static int 173*c3e25952SEmmanuel Vadot rk_usb2phy_clk_recalc(struct clknode *clk, uint64_t *freq) 174*c3e25952SEmmanuel Vadot { 175*c3e25952SEmmanuel Vadot 176*c3e25952SEmmanuel Vadot *freq = 480000000; 177*c3e25952SEmmanuel Vadot 178*c3e25952SEmmanuel Vadot return (0); 179*c3e25952SEmmanuel Vadot } 180*c3e25952SEmmanuel Vadot 181*c3e25952SEmmanuel Vadot static clknode_method_t rk_usb2phy_clk_clknode_methods[] = { 182*c3e25952SEmmanuel Vadot /* Device interface */ 183*c3e25952SEmmanuel Vadot 184*c3e25952SEmmanuel Vadot CLKNODEMETHOD(clknode_init, rk_usb2phy_clk_init), 185*c3e25952SEmmanuel Vadot CLKNODEMETHOD(clknode_set_gate, rk_usb2phy_clk_set_gate), 186*c3e25952SEmmanuel Vadot CLKNODEMETHOD(clknode_recalc_freq, rk_usb2phy_clk_recalc), 187*c3e25952SEmmanuel Vadot CLKNODEMETHOD_END 188*c3e25952SEmmanuel Vadot }; 189*c3e25952SEmmanuel Vadot 190*c3e25952SEmmanuel Vadot DEFINE_CLASS_1(rk_usb2phy_clk_clknode, rk_usb2phy_clk_clknode_class, 191*c3e25952SEmmanuel Vadot rk_usb2phy_clk_clknode_methods, sizeof(struct rk_usb2phy_clk_sc), 192*c3e25952SEmmanuel Vadot clknode_class); 193*c3e25952SEmmanuel Vadot 194*c3e25952SEmmanuel Vadot static int 195*c3e25952SEmmanuel Vadot rk_usb2phy_clk_ofw_map(struct clkdom *clkdom, uint32_t ncells, 196*c3e25952SEmmanuel Vadot phandle_t *cells, struct clknode **clk) 197*c3e25952SEmmanuel Vadot { 198*c3e25952SEmmanuel Vadot 199*c3e25952SEmmanuel Vadot if (ncells != 0) 200*c3e25952SEmmanuel Vadot return (ERANGE); 201*c3e25952SEmmanuel Vadot 202*c3e25952SEmmanuel Vadot *clk = clknode_find_by_id(clkdom, 0); 203*c3e25952SEmmanuel Vadot 204*c3e25952SEmmanuel Vadot if (*clk == NULL) 205*c3e25952SEmmanuel Vadot return (ENXIO); 206*c3e25952SEmmanuel Vadot return (0); 207*c3e25952SEmmanuel Vadot } 208*c3e25952SEmmanuel Vadot 209*c3e25952SEmmanuel Vadot static int 210*c3e25952SEmmanuel Vadot rk_usb2phy_export_clock(struct rk_usb2phy_softc *devsc) 211*c3e25952SEmmanuel Vadot { 212*c3e25952SEmmanuel Vadot struct clknode_init_def def; 213*c3e25952SEmmanuel Vadot struct rk_usb2phy_clk_sc *sc; 214*c3e25952SEmmanuel Vadot const char **clknames; 215*c3e25952SEmmanuel Vadot struct clkdom *clkdom; 216*c3e25952SEmmanuel Vadot struct clknode *clk; 217*c3e25952SEmmanuel Vadot clk_t clk_parent; 218*c3e25952SEmmanuel Vadot phandle_t node; 219*c3e25952SEmmanuel Vadot phandle_t regs[2]; 220*c3e25952SEmmanuel Vadot int i, nclocks, ncells, error; 221*c3e25952SEmmanuel Vadot 222*c3e25952SEmmanuel Vadot node = ofw_bus_get_node(devsc->dev); 223*c3e25952SEmmanuel Vadot 224*c3e25952SEmmanuel Vadot error = ofw_bus_parse_xref_list_get_length(node, "clocks", 225*c3e25952SEmmanuel Vadot "#clock-cells", &ncells); 226*c3e25952SEmmanuel Vadot if (error != 0 || ncells != 1) { 227*c3e25952SEmmanuel Vadot device_printf(devsc->dev, "couldn't find parent clock\n"); 228*c3e25952SEmmanuel Vadot return (ENXIO); 229*c3e25952SEmmanuel Vadot } 230*c3e25952SEmmanuel Vadot 231*c3e25952SEmmanuel Vadot nclocks = ofw_bus_string_list_to_array(node, "clock-output-names", 232*c3e25952SEmmanuel Vadot &clknames); 233*c3e25952SEmmanuel Vadot if (nclocks != 1) 234*c3e25952SEmmanuel Vadot return (ENXIO); 235*c3e25952SEmmanuel Vadot 236*c3e25952SEmmanuel Vadot clkdom = clkdom_create(devsc->dev); 237*c3e25952SEmmanuel Vadot clkdom_set_ofw_mapper(clkdom, rk_usb2phy_clk_ofw_map); 238*c3e25952SEmmanuel Vadot 239*c3e25952SEmmanuel Vadot memset(&def, 0, sizeof(def)); 240*c3e25952SEmmanuel Vadot def.id = 0; 241*c3e25952SEmmanuel Vadot def.name = clknames[0]; 242*c3e25952SEmmanuel Vadot def.parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP, M_WAITOK); 243*c3e25952SEmmanuel Vadot for (i = 0; i < ncells; i++) { 244*c3e25952SEmmanuel Vadot error = clk_get_by_ofw_index(devsc->dev, 0, i, &clk_parent); 245*c3e25952SEmmanuel Vadot if (error != 0) { 246*c3e25952SEmmanuel Vadot device_printf(devsc->dev, "cannot get clock %d\n", error); 247*c3e25952SEmmanuel Vadot return (ENXIO); 248*c3e25952SEmmanuel Vadot } 249*c3e25952SEmmanuel Vadot def.parent_names[i] = clk_get_name(clk_parent); 250*c3e25952SEmmanuel Vadot clk_release(clk_parent); 251*c3e25952SEmmanuel Vadot } 252*c3e25952SEmmanuel Vadot def.parent_cnt = ncells; 253*c3e25952SEmmanuel Vadot 254*c3e25952SEmmanuel Vadot clk = clknode_create(clkdom, &rk_usb2phy_clk_clknode_class, &def); 255*c3e25952SEmmanuel Vadot if (clk == NULL) { 256*c3e25952SEmmanuel Vadot device_printf(devsc->dev, "cannot create clknode\n"); 257*c3e25952SEmmanuel Vadot return (ENXIO); 258*c3e25952SEmmanuel Vadot } 259*c3e25952SEmmanuel Vadot 260*c3e25952SEmmanuel Vadot sc = clknode_get_softc(clk); 261*c3e25952SEmmanuel Vadot sc->clkdev = device_get_parent(devsc->dev); 262*c3e25952SEmmanuel Vadot sc->grf = devsc->grf; 263*c3e25952SEmmanuel Vadot sc->regs = (struct rk_usb2phy_regs *)ofw_bus_search_compatible(devsc->dev, compat_data)->ocd_data; 264*c3e25952SEmmanuel Vadot OF_getencprop(node, "reg", regs, sizeof(regs)); 265*c3e25952SEmmanuel Vadot sc->regs->clk_ctl.offset = regs[0]; 266*c3e25952SEmmanuel Vadot clknode_register(clkdom, clk); 267*c3e25952SEmmanuel Vadot 268*c3e25952SEmmanuel Vadot if (clkdom_finit(clkdom) != 0) { 269*c3e25952SEmmanuel Vadot device_printf(devsc->dev, "cannot finalize clkdom initialization\n"); 270*c3e25952SEmmanuel Vadot return (ENXIO); 271*c3e25952SEmmanuel Vadot } 272*c3e25952SEmmanuel Vadot 273*c3e25952SEmmanuel Vadot if (bootverbose) 274*c3e25952SEmmanuel Vadot clkdom_dump(clkdom); 275*c3e25952SEmmanuel Vadot 276*c3e25952SEmmanuel Vadot return (0); 277*c3e25952SEmmanuel Vadot } 278*c3e25952SEmmanuel Vadot 279*c3e25952SEmmanuel Vadot static int 280*c3e25952SEmmanuel Vadot rk_usb2phy_probe(device_t dev) 281*c3e25952SEmmanuel Vadot { 282*c3e25952SEmmanuel Vadot 283*c3e25952SEmmanuel Vadot if (!ofw_bus_status_okay(dev)) 284*c3e25952SEmmanuel Vadot return (ENXIO); 285*c3e25952SEmmanuel Vadot 286*c3e25952SEmmanuel Vadot if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) 287*c3e25952SEmmanuel Vadot return (ENXIO); 288*c3e25952SEmmanuel Vadot 289*c3e25952SEmmanuel Vadot device_set_desc(dev, "Rockchip RK3399 USB2PHY"); 290*c3e25952SEmmanuel Vadot return (BUS_PROBE_DEFAULT); 291*c3e25952SEmmanuel Vadot } 292*c3e25952SEmmanuel Vadot 293*c3e25952SEmmanuel Vadot static int 294*c3e25952SEmmanuel Vadot rk_usb2phy_attach(device_t dev) 295*c3e25952SEmmanuel Vadot { 296*c3e25952SEmmanuel Vadot struct rk_usb2phy_softc *sc; 297*c3e25952SEmmanuel Vadot struct phynode_init_def phy_init; 298*c3e25952SEmmanuel Vadot struct phynode *phynode; 299*c3e25952SEmmanuel Vadot phandle_t node, host; 300*c3e25952SEmmanuel Vadot int err; 301*c3e25952SEmmanuel Vadot 302*c3e25952SEmmanuel Vadot sc = device_get_softc(dev); 303*c3e25952SEmmanuel Vadot sc->dev = dev; 304*c3e25952SEmmanuel Vadot node = ofw_bus_get_node(dev); 305*c3e25952SEmmanuel Vadot 306*c3e25952SEmmanuel Vadot if (syscon_get_handle_default(dev, &sc->grf) != 0) { 307*c3e25952SEmmanuel Vadot device_printf(dev, "Cannot get syscon handle\n"); 308*c3e25952SEmmanuel Vadot return (ENXIO); 309*c3e25952SEmmanuel Vadot } 310*c3e25952SEmmanuel Vadot 311*c3e25952SEmmanuel Vadot if (clk_get_by_ofw_name(dev, 0, "phyclk", &sc->clk) != 0) { 312*c3e25952SEmmanuel Vadot device_printf(dev, "Cannot get clock\n"); 313*c3e25952SEmmanuel Vadot return (ENXIO); 314*c3e25952SEmmanuel Vadot } 315*c3e25952SEmmanuel Vadot err = clk_enable(sc->clk); 316*c3e25952SEmmanuel Vadot if (err != 0) { 317*c3e25952SEmmanuel Vadot device_printf(dev, "Could not enable clock %s\n", 318*c3e25952SEmmanuel Vadot clk_get_name(sc->clk)); 319*c3e25952SEmmanuel Vadot return (ENXIO); 320*c3e25952SEmmanuel Vadot } 321*c3e25952SEmmanuel Vadot 322*c3e25952SEmmanuel Vadot err = rk_usb2phy_export_clock(sc); 323*c3e25952SEmmanuel Vadot if (err != 0) 324*c3e25952SEmmanuel Vadot return (err); 325*c3e25952SEmmanuel Vadot 326*c3e25952SEmmanuel Vadot /* Only host is supported right now */ 327*c3e25952SEmmanuel Vadot 328*c3e25952SEmmanuel Vadot host = ofw_bus_find_child(node, "host-port"); 329*c3e25952SEmmanuel Vadot if (host == 0) { 330*c3e25952SEmmanuel Vadot device_printf(dev, "Cannot find host-port child node\n"); 331*c3e25952SEmmanuel Vadot return (ENXIO); 332*c3e25952SEmmanuel Vadot } 333*c3e25952SEmmanuel Vadot 334*c3e25952SEmmanuel Vadot if (!ofw_bus_node_status_okay(host)) { 335*c3e25952SEmmanuel Vadot device_printf(dev, "host-port isn't okay\n"); 336*c3e25952SEmmanuel Vadot return (0); 337*c3e25952SEmmanuel Vadot } 338*c3e25952SEmmanuel Vadot 339*c3e25952SEmmanuel Vadot regulator_get_by_ofw_property(dev, host, "phy-supply", &sc->phy_supply); 340*c3e25952SEmmanuel Vadot phy_init.id = RK3399_USBPHY_HOST; 341*c3e25952SEmmanuel Vadot phy_init.ofw_node = host; 342*c3e25952SEmmanuel Vadot phynode = phynode_create(dev, &rk_usb2phy_phynode_class, &phy_init); 343*c3e25952SEmmanuel Vadot if (phynode == NULL) { 344*c3e25952SEmmanuel Vadot device_printf(dev, "failed to create host USB2PHY\n"); 345*c3e25952SEmmanuel Vadot return (ENXIO); 346*c3e25952SEmmanuel Vadot } 347*c3e25952SEmmanuel Vadot if (phynode_register(phynode) == NULL) { 348*c3e25952SEmmanuel Vadot device_printf(dev, "failed to register host USB2PHY\n"); 349*c3e25952SEmmanuel Vadot return (ENXIO); 350*c3e25952SEmmanuel Vadot } 351*c3e25952SEmmanuel Vadot 352*c3e25952SEmmanuel Vadot OF_device_register_xref(OF_xref_from_node(host), dev); 353*c3e25952SEmmanuel Vadot 354*c3e25952SEmmanuel Vadot return (0); 355*c3e25952SEmmanuel Vadot } 356*c3e25952SEmmanuel Vadot 357*c3e25952SEmmanuel Vadot static device_method_t rk_usb2phy_methods[] = { 358*c3e25952SEmmanuel Vadot /* Device interface */ 359*c3e25952SEmmanuel Vadot DEVMETHOD(device_probe, rk_usb2phy_probe), 360*c3e25952SEmmanuel Vadot DEVMETHOD(device_attach, rk_usb2phy_attach), 361*c3e25952SEmmanuel Vadot 362*c3e25952SEmmanuel Vadot DEVMETHOD_END 363*c3e25952SEmmanuel Vadot }; 364*c3e25952SEmmanuel Vadot 365*c3e25952SEmmanuel Vadot static driver_t rk_usb2phy_driver = { 366*c3e25952SEmmanuel Vadot "rk_usb2phy", 367*c3e25952SEmmanuel Vadot rk_usb2phy_methods, 368*c3e25952SEmmanuel Vadot sizeof(struct rk_usb2phy_softc) 369*c3e25952SEmmanuel Vadot }; 370*c3e25952SEmmanuel Vadot 371*c3e25952SEmmanuel Vadot static devclass_t rk_usb2phy_devclass; 372*c3e25952SEmmanuel Vadot EARLY_DRIVER_MODULE(rk_usb2phy, simplebus, rk_usb2phy_driver, 373*c3e25952SEmmanuel Vadot rk_usb2phy_devclass, 0, 0, BUS_PASS_SUPPORTDEV + BUS_PASS_ORDER_MIDDLE); 374*c3e25952SEmmanuel Vadot MODULE_VERSION(rk_usb2phy, 1); 375