Module Name: src Committed By: jmcneill Date: Sun Apr 16 12:28:21 UTC 2017
Modified Files: src/sys/arch/arm/nvidia: tegra124_car.c tegra_ahcisata.c tegra_drm.c tegra_hdaudio.c tegra_soctherm.c tegra_timer.c tegra_xusb.c src/sys/dev/clk: clk.c clk.h clk_backend.h Log Message: Add support for multiple clock domains in clk API. To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/nvidia/tegra124_car.c \ src/sys/arch/arm/nvidia/tegra_ahcisata.c cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/nvidia/tegra_drm.c cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/nvidia/tegra_hdaudio.c cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/nvidia/tegra_soctherm.c cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/nvidia/tegra_timer.c \ src/sys/arch/arm/nvidia/tegra_xusb.c cvs rdiff -u -r1.1 -r1.2 src/sys/dev/clk/clk.c src/sys/dev/clk/clk.h \ src/sys/dev/clk/clk_backend.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/nvidia/tegra124_car.c diff -u src/sys/arch/arm/nvidia/tegra124_car.c:1.9 src/sys/arch/arm/nvidia/tegra124_car.c:1.10 --- src/sys/arch/arm/nvidia/tegra124_car.c:1.9 Fri Apr 14 09:50:56 2017 +++ src/sys/arch/arm/nvidia/tegra124_car.c Sun Apr 16 12:28:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra124_car.c,v 1.9 2017/04/14 09:50:56 jmcneill Exp $ */ +/* $NetBSD: tegra124_car.c,v 1.10 2017/04/16 12:28:21 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra124_car.c,v 1.9 2017/04/14 09:50:56 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra124_car.c,v 1.10 2017/04/16 12:28:21 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -626,8 +626,6 @@ static struct tegra_clk tegra124_car_clo CLK_GATE_H("fuse", "clk_m", CAR_DEV_H_FUSE), CLK_GATE_U("soc_therm", "div_soc_therm", CAR_DEV_U_SOC_THERM), CLK_GATE_V("tsensor", "div_tsensor", CAR_DEV_V_TSENSOR), - CLK_GATE_SIMPLE("watchdog", "clk_m", CAR_RST_SOURCE_REG, - CAR_RST_SOURCE_WDT_EN|CAR_RST_SOURCE_WDT_SYS_RST_EN), CLK_GATE_L("host1x", "div_host1x", CAR_DEV_L_HOST1X), CLK_GATE_L("disp1", "mux_disp1", CAR_DEV_L_DISP1), CLK_GATE_L("disp2", "mux_disp2", CAR_DEV_L_DISP2), @@ -639,6 +637,22 @@ static struct tegra_clk tegra124_car_clo CLK_GATE_X("gpu", "pll_ref", CAR_DEV_X_GPU), }; +struct tegra124_init_parent { + const char *clock; + const char *parent; +} tegra124_init_parents[] = { + { "sata_oob", "pll_p_out0" }, + { "sata", "pll_p_out0" }, + { "hda", "pll_p_out0" }, + { "hda2codec_2x", "pll_p_out0" }, + { "soc_therm", "pll_p_out0" }, + { "tsensor", "clk_m" }, + { "xusb_host_src", "pll_p_out0" }, + { "xusb_falcon_src", "pll_p_out0" }, + { "xusb_ss_src", "pll_u_480" }, + { "xusb_fs_src", "pll_u_48" }, +}; + struct tegra124_car_rst { u_int set_reg; u_int clr_reg; @@ -674,6 +688,8 @@ struct tegra124_car_softc { bus_space_tag_t sc_bst; bus_space_handle_t sc_bsh; + struct clk_domain sc_clkdom; + u_int sc_clock_cells; u_int sc_reset_cells; @@ -684,6 +700,8 @@ struct tegra124_car_softc { static void tegra124_car_init(struct tegra124_car_softc *); static void tegra124_car_utmip_init(struct tegra124_car_softc *); static void tegra124_car_xusb_init(struct tegra124_car_softc *); +static void tegra124_car_watchdog_init(struct tegra124_car_softc *); +static void tegra124_car_parent_init(struct tegra124_car_softc *); static void tegra124_car_rnd_attach(device_t); static void tegra124_car_rnd_callback(size_t, void *); @@ -715,7 +733,7 @@ tegra124_car_attach(device_t parent, dev const int phandle = faa->faa_phandle; bus_addr_t addr; bus_size_t size; - int error; + int error, n; if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { aprint_error(": couldn't get registers\n"); @@ -737,7 +755,10 @@ tegra124_car_attach(device_t parent, dev aprint_naive("\n"); aprint_normal(": CAR\n"); - clk_backend_register("tegra124", &tegra124_car_clock_funcs, sc); + sc->sc_clkdom.funcs = &tegra124_car_clock_funcs; + sc->sc_clkdom.priv = sc; + for (n = 0; n < __arraycount(tegra124_car_clocks); n++) + tegra124_car_clocks[n].base.domain = &sc->sc_clkdom; fdtbus_register_clock_controller(self, phandle, &tegra124_car_fdtclock_funcs); @@ -752,8 +773,35 @@ tegra124_car_attach(device_t parent, dev static void tegra124_car_init(struct tegra124_car_softc *sc) { + tegra124_car_parent_init(sc); tegra124_car_utmip_init(sc); tegra124_car_xusb_init(sc); + tegra124_car_watchdog_init(sc); +} + +static void +tegra124_car_parent_init(struct tegra124_car_softc *sc) +{ + struct clk *clk, *clk_parent; + int error; + u_int n; + + for (n = 0; n < __arraycount(tegra124_init_parents); n++) { + clk = clk_get(&sc->sc_clkdom, tegra124_init_parents[n].clock); + KASSERT(clk != NULL); + clk_parent = clk_get(&sc->sc_clkdom, + tegra124_init_parents[n].parent); + KASSERT(clk_parent != NULL); + + error = clk_set_parent(clk, clk_parent); + if (error) { + aprint_error_dev(sc->sc_dev, + "couldn't set '%s' parent to '%s': %d\n", + clk->name, clk_parent->name, error); + } + clk_put(clk_parent); + clk_put(clk); + } } static void @@ -835,6 +883,17 @@ tegra124_car_xusb_init(struct tegra124_c } static void +tegra124_car_watchdog_init(struct tegra124_car_softc *sc) +{ + const bus_space_tag_t bst = sc->sc_bst; + const bus_space_handle_t bsh = sc->sc_bsh; + + /* Enable watchdog timer reset for system */ + tegra_reg_set_clear(bst, bsh, CAR_RST_SOURCE_REG, + CAR_RST_SOURCE_WDT_EN|CAR_RST_SOURCE_WDT_SYS_RST_EN, 0); +} + +static void tegra124_car_rnd_attach(device_t self) { struct tegra124_car_softc * const sc = device_private(self); Index: src/sys/arch/arm/nvidia/tegra_ahcisata.c diff -u src/sys/arch/arm/nvidia/tegra_ahcisata.c:1.9 src/sys/arch/arm/nvidia/tegra_ahcisata.c:1.10 --- src/sys/arch/arm/nvidia/tegra_ahcisata.c:1.9 Tue Dec 22 22:10:36 2015 +++ src/sys/arch/arm/nvidia/tegra_ahcisata.c Sun Apr 16 12:28:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_ahcisata.c,v 1.9 2015/12/22 22:10:36 jmcneill Exp $ */ +/* $NetBSD: tegra_ahcisata.c,v 1.10 2017/04/16 12:28:21 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra_ahcisata.c,v 1.9 2015/12/22 22:10:36 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_ahcisata.c,v 1.10 2017/04/16 12:28:21 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -284,26 +284,13 @@ static int tegra_ahcisata_init_clocks(struct tegra_ahcisata_softc *sc) { device_t self = sc->sc.sc_atac.atac_dev; - struct clk *pll_p_out0; int error; - pll_p_out0 = clk_get("pll_p_out0"); - if (pll_p_out0 == NULL) { - aprint_error_dev(self, "couldn't find pll_p_out0\n"); - return ENOENT; - } - /* Assert resets */ fdtbus_reset_assert(sc->sc_rst_sata); fdtbus_reset_assert(sc->sc_rst_sata_cold); - /* Set SATA_OOB clock source to PLLP, 204MHz */ - error = clk_set_parent(sc->sc_clk_sata_oob, pll_p_out0); - if (error) { - aprint_error_dev(self, "couldn't set sata-oob parent: %d\n", - error); - return error; - } + /* Set SATA_OOB clock source to 204MHz */ error = clk_set_rate(sc->sc_clk_sata_oob, 204000000); if (error) { aprint_error_dev(self, "couldn't set sata-oob rate: %d\n", @@ -311,12 +298,7 @@ tegra_ahcisata_init_clocks(struct tegra_ return error; } - /* Set SATA clock source to PLLP, 102MHz */ - error = clk_set_parent(sc->sc_clk_sata, pll_p_out0); - if (error) { - aprint_error_dev(self, "couldn't set sata parent: %d\n", error); - return error; - } + /* Set SATA clock source to 102MHz */ error = clk_set_rate(sc->sc_clk_sata, 102000000); if (error) { aprint_error_dev(self, "couldn't set sata rate: %d\n", error); Index: src/sys/arch/arm/nvidia/tegra_drm.c diff -u src/sys/arch/arm/nvidia/tegra_drm.c:1.6 src/sys/arch/arm/nvidia/tegra_drm.c:1.7 --- src/sys/arch/arm/nvidia/tegra_drm.c:1.6 Sat Jan 30 00:00:56 2016 +++ src/sys/arch/arm/nvidia/tegra_drm.c Sun Apr 16 12:28:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_drm.c,v 1.6 2016/01/30 00:00:56 riastradh Exp $ */ +/* $NetBSD: tegra_drm.c,v 1.7 2017/04/16 12:28:21 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra_drm.c,v 1.6 2016/01/30 00:00:56 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_drm.c,v 1.7 2017/04/16 12:28:21 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -126,7 +126,6 @@ tegra_drm_attach(device_t parent, device "hdmi-supply", "pll-supply", "vdd-supply" }; struct fdtbus_regulator *reg; - struct clk *pll_p_out0; u_int n, ndc; sc->sc_dev = self; @@ -192,24 +191,7 @@ tegra_drm_attach(device_t parent, device } } - pll_p_out0 = clk_get("pll_p_out0"); - if (pll_p_out0 == NULL) { - aprint_error_dev(self, "couldn't get clock pll_p_out0\n"); - return; - } fdtbus_reset_assert(sc->sc_rst_host1x); - error = clk_set_parent(sc->sc_clk_host1x, pll_p_out0); - if (error) { - aprint_error_dev(self, "couldn't set host1x clock parent: %d\n", - error); - return; - } - error = clk_set_rate(sc->sc_clk_host1x, 408000000); - if (error) { - aprint_error_dev(self, "couldn't set host1x frequency: %d\n", - error); - return; - } error = clk_enable(sc->sc_clk_host1x); if (error) { aprint_error_dev(self, "couldn't enable clock host1x: %d\n", @@ -217,7 +199,6 @@ tegra_drm_attach(device_t parent, device return; } fdtbus_reset_deassert(sc->sc_rst_host1x); - clk_put(pll_p_out0); prop_dictionary_get_bool(prop, "force-dvi", &sc->sc_force_dvi); Index: src/sys/arch/arm/nvidia/tegra_hdaudio.c diff -u src/sys/arch/arm/nvidia/tegra_hdaudio.c:1.7 src/sys/arch/arm/nvidia/tegra_hdaudio.c:1.8 --- src/sys/arch/arm/nvidia/tegra_hdaudio.c:1.7 Wed Dec 23 12:44:06 2015 +++ src/sys/arch/arm/nvidia/tegra_hdaudio.c Sun Apr 16 12:28:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_hdaudio.c,v 1.7 2015/12/23 12:44:06 jmcneill Exp $ */ +/* $NetBSD: tegra_hdaudio.c,v 1.8 2017/04/16 12:28:21 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra_hdaudio.c,v 1.7 2015/12/23 12:44:06 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_hdaudio.c,v 1.8 2017/04/16 12:28:21 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -183,26 +183,14 @@ static int tegra_hdaudio_init_clocks(struct tegra_hdaudio_softc *sc) { device_t self = sc->sc.sc_dev; - struct clk *pll_p_out0; int error; - pll_p_out0 = clk_get("pll_p_out0"); - if (pll_p_out0 == NULL) { - aprint_error_dev(self, "couldn't find pll_p_out0\n"); - return ENOENT; - } - /* Assert resets */ fdtbus_reset_assert(sc->sc_rst_hda); fdtbus_reset_assert(sc->sc_rst_hda2hdmi); fdtbus_reset_assert(sc->sc_rst_hda2codec_2x); /* Set hda to 48MHz and enable it */ - error = clk_set_parent(sc->sc_clk_hda, pll_p_out0); - if (error) { - aprint_error_dev(self, "coulnd't set hda parent: %d\n", error); - return error; - } error = clk_set_rate(sc->sc_clk_hda, 48000000); if (error) { aprint_error_dev(self, "couldn't set hda frequency: %d\n", @@ -225,12 +213,6 @@ tegra_hdaudio_init_clocks(struct tegra_h } /* Set hda2codec_2x to 48MHz and enable it */ - error = clk_set_parent(sc->sc_clk_hda2codec_2x, pll_p_out0); - if (error) { - aprint_error_dev(self, "couldn't set hda2codec_2x parent: %d\n", - error); - return error; - } error = clk_set_rate(sc->sc_clk_hda2codec_2x, 48000000); if (error) { aprint_error_dev(self, Index: src/sys/arch/arm/nvidia/tegra_soctherm.c diff -u src/sys/arch/arm/nvidia/tegra_soctherm.c:1.3 src/sys/arch/arm/nvidia/tegra_soctherm.c:1.4 --- src/sys/arch/arm/nvidia/tegra_soctherm.c:1.3 Tue Dec 22 22:10:36 2015 +++ src/sys/arch/arm/nvidia/tegra_soctherm.c Sun Apr 16 12:28:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_soctherm.c,v 1.3 2015/12/22 22:10:36 jmcneill Exp $ */ +/* $NetBSD: tegra_soctherm.c,v 1.4 2017/04/16 12:28:21 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra_soctherm.c,v 1.3 2015/12/22 22:10:36 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_soctherm.c,v 1.4 2017/04/16 12:28:21 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -135,7 +135,7 @@ struct tegra_soctherm_softc { }; static int tegra_soctherm_init_clocks(struct tegra_soctherm_softc *); -static void tegra_soctherm_init_sensors(struct tegra_soctherm_softc *); +static void tegra_soctherm_init_sensors(device_t); static void tegra_soctherm_init_sensor(struct tegra_soctherm_softc *, struct tegra_soctherm_sensor *); static void tegra_soctherm_refresh(struct sysmon_envsys *, envsys_data_t *); @@ -220,35 +220,16 @@ tegra_soctherm_attach(device_t parent, d if (tegra_soctherm_init_clocks(sc) != 0) return; - tegra_soctherm_init_sensors(sc); + config_defer(self, tegra_soctherm_init_sensors); } static int tegra_soctherm_init_clocks(struct tegra_soctherm_softc *sc) { - struct clk *pll_p_out0; - struct clk *clk_m; int error; - pll_p_out0 = clk_get("pll_p_out0"); - if (pll_p_out0 == NULL) { - aprint_error_dev(sc->sc_dev, "couldn't find pll_p_out0\n"); - return ENOENT; - } - clk_m = clk_get("clk_m"); - if (clk_m == NULL) { - aprint_error_dev(sc->sc_dev, "couldn't find clk_m\n"); - return ENOENT; - } - fdtbus_reset_assert(sc->sc_rst_soctherm); - error = clk_set_parent(sc->sc_clk_soctherm, pll_p_out0); - if (error) { - aprint_error_dev(sc->sc_dev, - "couldn't set soctherm parent: %d\n", error); - return error; - } error = clk_set_rate(sc->sc_clk_soctherm, 51000000); if (error) { aprint_error_dev(sc->sc_dev, @@ -256,12 +237,6 @@ tegra_soctherm_init_clocks(struct tegra_ return error; } - error = clk_set_parent(sc->sc_clk_tsensor, clk_m); - if (error) { - aprint_error_dev(sc->sc_dev, - "couldn't set tsensor parent: %d\n", error); - return error; - } error = clk_set_rate(sc->sc_clk_tsensor, 400000); if (error) { aprint_error_dev(sc->sc_dev, @@ -289,8 +264,9 @@ tegra_soctherm_init_clocks(struct tegra_ } static void -tegra_soctherm_init_sensors(struct tegra_soctherm_softc *sc) +tegra_soctherm_init_sensors(device_t dev) { + struct tegra_soctherm_softc * const sc = device_private(dev); const struct tegra_soctherm_config *config = sc->sc_config; const u_int nsensors = __arraycount(tegra_soctherm_sensors); const size_t len = sizeof(*sc->sc_sensors) * nsensors; Index: src/sys/arch/arm/nvidia/tegra_timer.c diff -u src/sys/arch/arm/nvidia/tegra_timer.c:1.4 src/sys/arch/arm/nvidia/tegra_timer.c:1.5 --- src/sys/arch/arm/nvidia/tegra_timer.c:1.4 Thu Dec 24 12:47:38 2015 +++ src/sys/arch/arm/nvidia/tegra_timer.c Sun Apr 16 12:28:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_timer.c,v 1.4 2015/12/24 12:47:38 jmcneill Exp $ */ +/* $NetBSD: tegra_timer.c,v 1.5 2017/04/16 12:28:21 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra_timer.c,v 1.4 2015/12/24 12:47:38 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_timer.c,v 1.5 2017/04/16 12:28:21 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -54,7 +54,6 @@ struct tegra_timer_softc { device_t sc_dev; bus_space_tag_t sc_bst; bus_space_handle_t sc_bsh; - struct clk *sc_clk_watchdog; struct sysmon_wdog sc_smw; }; @@ -94,9 +93,6 @@ tegra_timer_attach(device_t parent, devi aprint_error(": couldn't get registers\n"); return; } - sc->sc_clk_watchdog = fdtbus_clock_get(faa->faa_phandle, "watchdog"); - if (sc->sc_clk_watchdog == NULL) - sc->sc_clk_watchdog = clk_get("watchdog"); sc->sc_dev = self; sc->sc_bst = faa->faa_bst; @@ -109,21 +105,19 @@ tegra_timer_attach(device_t parent, devi aprint_naive("\n"); aprint_normal(": Timers\n"); - if (sc->sc_clk_watchdog) { - sc->sc_smw.smw_name = device_xname(self); - sc->sc_smw.smw_cookie = sc; - sc->sc_smw.smw_setmode = tegra_timer_wdt_setmode; - sc->sc_smw.smw_tickle = tegra_timer_wdt_tickle; - sc->sc_smw.smw_period = TEGRA_TIMER_WDOG_PERIOD_DEFAULT; - - aprint_normal_dev(self, - "default watchdog period is %u seconds\n", - sc->sc_smw.smw_period); - - if (sysmon_wdog_register(&sc->sc_smw) != 0) { - aprint_error_dev(self, - "couldn't register with sysmon\n"); - } + sc->sc_smw.smw_name = device_xname(self); + sc->sc_smw.smw_cookie = sc; + sc->sc_smw.smw_setmode = tegra_timer_wdt_setmode; + sc->sc_smw.smw_tickle = tegra_timer_wdt_tickle; + sc->sc_smw.smw_period = TEGRA_TIMER_WDOG_PERIOD_DEFAULT; + + aprint_normal_dev(self, + "default watchdog period is %u seconds\n", + sc->sc_smw.smw_period); + + if (sysmon_wdog_register(&sc->sc_smw) != 0) { + aprint_error_dev(self, + "couldn't register with sysmon\n"); } } @@ -134,7 +128,6 @@ tegra_timer_wdt_setmode(struct sysmon_wd if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) { TIMER_SET_CLEAR(sc, TMR1_PTV_REG, 0, TMR_PTV_EN); - return clk_disable(sc->sc_clk_watchdog); } else { if (smw->smw_period == WDOG_PERIOD_DEFAULT) { sc->sc_smw.smw_period = TEGRA_TIMER_WDOG_PERIOD_DEFAULT; @@ -147,8 +140,9 @@ tegra_timer_wdt_setmode(struct sysmon_wd TIMER_WRITE(sc, TMR1_PTV_REG, TMR_PTV_EN | TMR_PTV_PER | __SHIFTIN(tval, TMR_PTV_VAL)); TIMER_WRITE(sc, TMR1_PCR_REG, TMR_PCR_INTR_CLR); - return clk_enable(sc->sc_clk_watchdog); } + + return 0; } static int Index: src/sys/arch/arm/nvidia/tegra_xusb.c diff -u src/sys/arch/arm/nvidia/tegra_xusb.c:1.4 src/sys/arch/arm/nvidia/tegra_xusb.c:1.5 --- src/sys/arch/arm/nvidia/tegra_xusb.c:1.4 Fri Apr 14 00:19:34 2017 +++ src/sys/arch/arm/nvidia/tegra_xusb.c Sun Apr 16 12:28:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_xusb.c,v 1.4 2017/04/14 00:19:34 jmcneill Exp $ */ +/* $NetBSD: tegra_xusb.c,v 1.5 2017/04/16 12:28:21 jmcneill Exp $ */ /* * Copyright (c) 2016 Jonathan A. Kollasch @@ -30,7 +30,7 @@ #include "opt_tegra.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra_xusb.c,v 1.4 2017/04/14 00:19:34 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_xusb.c,v 1.5 2017/04/16 12:28:21 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -201,15 +201,6 @@ tegra_xusb_attach(device_t parent, devic } aprint_normal_dev(self, "interrupting on %s\n", intrstr); - struct clk * const pll_p_out0 = clk_get("pll_p_out0"); - KASSERT(pll_p_out0 != NULL); - - struct clk * const pll_u_48 = clk_get("pll_u_48"); - KASSERT(pll_u_48 != NULL); - - struct clk * const pll_u_480 = clk_get("pll_u_480"); - KASSERT(pll_u_480 != NULL); - clk = fdtbus_clock_get(faa->faa_phandle, "pll_e"); rate = clk_get_rate(clk); error = clk_enable(clk); /* XXX set frequency */ @@ -217,9 +208,6 @@ tegra_xusb_attach(device_t parent, devic tegra_xusb_attach_check(sc, error, "failed to enable pll_e clock"); clk = fdtbus_clock_get(faa->faa_phandle, "xusb_host_src"); - error = clk_set_parent(clk, pll_p_out0); - tegra_xusb_attach_check(sc, error, "failed to set xusb_host_src clock parent"); - rate = clk_get_rate(clk); device_printf(sc->sc_dev, "rate %u error %d\n", rate, error); error = clk_set_rate(clk, 102000000); @@ -231,9 +219,6 @@ tegra_xusb_attach(device_t parent, devic tegra_xusb_attach_check(sc, error, "failed to enable xusb_host_src clock"); clk = fdtbus_clock_get(faa->faa_phandle, "xusb_falcon_src"); - error = clk_set_parent(clk, pll_p_out0); - tegra_xusb_attach_check(sc, error, "failed to set xusb_falcon_src clock parent"); - rate = clk_get_rate(clk); device_printf(sc->sc_dev, "rate %u error %d\n", rate, error); error = clk_set_rate(clk, 204000000); @@ -258,18 +243,15 @@ tegra_xusb_attach(device_t parent, devic psc->sc_clk_ss_src = fdtbus_clock_get(faa->faa_phandle, "xusb_ss_src"); tegra_xusb_attach_check(sc, psc->sc_clk_ss_src == NULL, "failed to get xusb_ss_src clock"); + rate = clk_get_rate(psc->sc_clk_ss_src); device_printf(sc->sc_dev, "xusb_ss_src rate %u\n", rate); - error = clk_set_rate(psc->sc_clk_ss_src, 2000000); rate = clk_get_rate(psc->sc_clk_ss_src); device_printf(sc->sc_dev, "xusb_ss_src rate %u error %d\n", rate, error); tegra_xusb_attach_check(sc, error, "failed to get xusb_ss_src clock rate"); - error = clk_set_parent(psc->sc_clk_ss_src, pll_u_480); - tegra_xusb_attach_check(sc, error, "failed to set xusb_ss_src clock parent"); - rate = clk_get_rate(psc->sc_clk_ss_src); device_printf(sc->sc_dev, "ss_src rate %u\n", rate); tegra_xusb_attach_check(sc, error, "failed to set xusb_ss_src clock rate"); @@ -291,9 +273,6 @@ tegra_xusb_attach(device_t parent, devic #endif clk = fdtbus_clock_get(faa->faa_phandle, "xusb_fs_src"); - error = clk_set_parent(clk, pll_u_48); - tegra_xusb_attach_check(sc, error, "failed to set xusb_fs_src clock parent"); - rate = clk_get_rate(clk); error = clk_enable(clk); /* XXX set frequency */ device_printf(sc->sc_dev, "rate %u error %d\n", rate, error); Index: src/sys/dev/clk/clk.c diff -u src/sys/dev/clk/clk.c:1.1 src/sys/dev/clk/clk.c:1.2 --- src/sys/dev/clk/clk.c:1.1 Sat Dec 5 13:31:07 2015 +++ src/sys/dev/clk/clk.c Sun Apr 16 12:28:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: clk.c,v 1.1 2015/12/05 13:31:07 jmcneill Exp $ */ +/* $NetBSD: clk.c,v 1.2 2017/04/16 12:28:21 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,47 +27,29 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: clk.c,v 1.1 2015/12/05 13:31:07 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: clk.c,v 1.2 2017/04/16 12:28:21 jmcneill Exp $"); #include <sys/param.h> #include <dev/clk/clk.h> #include <dev/clk/clk_backend.h> -static const char *clk_backend = NULL; -static const struct clk_funcs *clk_funcs = NULL; -static void *clk_priv = NULL; - -int -clk_backend_register(const char *name, const struct clk_funcs *funcs, void *priv) -{ - KASSERT(clk_funcs == NULL); - - clk_backend = name; - clk_funcs = funcs; - clk_priv = priv; - - return 0; -} - struct clk * -clk_get(const char *name) +clk_get(struct clk_domain *domain, const char *name) { - if (clk_funcs == NULL) - return NULL; - return clk_funcs->get(clk_priv, name); + return domain->funcs->get(domain->priv, name); } void clk_put(struct clk *clk) { - return clk_funcs->put(clk_priv, clk); + return clk->domain->funcs->put(clk->domain->priv, clk); } u_int clk_get_rate(struct clk *clk) { - return clk_funcs->get_rate(clk_priv, clk); + return clk->domain->funcs->get_rate(clk->domain->priv, clk); } int @@ -75,31 +57,44 @@ clk_set_rate(struct clk *clk, u_int rate { if (clk->flags & CLK_SET_RATE_PARENT) { return clk_set_rate(clk_get_parent(clk), rate); + } else if (clk->domain->funcs->set_rate) { + return clk->domain->funcs->set_rate(clk->domain->priv, + clk, rate); } else { - return clk_funcs->set_rate(clk_priv, clk, rate); + return EINVAL; } } int clk_enable(struct clk *clk) { - return clk_funcs->enable(clk_priv, clk); + if (clk->domain->funcs->enable) + return clk->domain->funcs->enable(clk->domain->priv, clk); + else + return 0; } int clk_disable(struct clk *clk) { - return clk_funcs->disable(clk_priv, clk); + if (clk->domain->funcs->disable) + return clk->domain->funcs->disable(clk->domain->priv, clk); + else + return EINVAL; } int clk_set_parent(struct clk *clk, struct clk *parent_clk) { - return clk_funcs->set_parent(clk_priv, clk, parent_clk); + if (clk->domain->funcs->set_parent) + return clk->domain->funcs->set_parent(clk->domain->priv, + clk, parent_clk); + else + return EINVAL; } struct clk * clk_get_parent(struct clk *clk) { - return clk_funcs->get_parent(clk_priv, clk); + return clk->domain->funcs->get_parent(clk->domain->priv, clk); } Index: src/sys/dev/clk/clk.h diff -u src/sys/dev/clk/clk.h:1.1 src/sys/dev/clk/clk.h:1.2 --- src/sys/dev/clk/clk.h:1.1 Sat Dec 5 13:31:07 2015 +++ src/sys/dev/clk/clk.h Sun Apr 16 12:28:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: clk.h,v 1.1 2015/12/05 13:31:07 jmcneill Exp $ */ +/* $NetBSD: clk.h,v 1.2 2017/04/16 12:28:21 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -29,9 +29,10 @@ #ifndef _DEV_CLK_CLK_H #define _DEV_CLK_CLK_H +struct clk_domain; struct clk; -struct clk * clk_get(const char *); +struct clk * clk_get(struct clk_domain *, const char *); void clk_put(struct clk *); u_int clk_get_rate(struct clk *); int clk_set_rate(struct clk *, u_int); Index: src/sys/dev/clk/clk_backend.h diff -u src/sys/dev/clk/clk_backend.h:1.1 src/sys/dev/clk/clk_backend.h:1.2 --- src/sys/dev/clk/clk_backend.h:1.1 Sat Dec 5 13:31:07 2015 +++ src/sys/dev/clk/clk_backend.h Sun Apr 16 12:28:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: clk_backend.h,v 1.1 2015/12/05 13:31:07 jmcneill Exp $ */ +/* $NetBSD: clk_backend.h,v 1.2 2017/04/16 12:28:21 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -31,7 +31,13 @@ #include <dev/clk/clk.h> +struct clk_domain { + const struct clk_funcs *funcs; + void *priv; +}; + struct clk { + struct clk_domain *domain; const char *name; u_int flags; #define CLK_SET_RATE_PARENT 0x01 @@ -49,6 +55,4 @@ struct clk_funcs { struct clk *(*get_parent)(void *, struct clk *); }; -int clk_backend_register(const char *, const struct clk_funcs *, void *); - #endif /* _DEV_CLK_CLK_BACKEND_H */