diff --git a/sys/arm/ti/clk/am33xx.h b/sys/arm/ti/clk/am33xx.h
new file mode 100644
--- /dev/null
+++ b/sys/arm/ti/clk/am33xx.h
@@ -0,0 +1,1233 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024 Oskar Holmlund <oskar.holmlund@ohdata.se>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __AM33XX_H__
+#define __AM33XX_H__
+
+#include <arm/ti/clk/ti_clock_common.h>
+#include <dev/clk/clk_link.h>
+#include <dt-bindings/clock/am3.h>
+
+/* === ti_sysc.c === */
+PLIST(target_module_7000) = {
+	"l4-wkup-clkctrl@0_8",
+	"l4-wkup-clkctrl@0_9"
+}; /* gpio0 */
+PLIST(target_module_9000) = { "l4-wkup-clkctrl@0_b4" }; /* uart0 */
+PLIST(target_module_b000) = { "l4-wkup-clkctrl@0_b8" }; /* i2c1 */
+PLIST(target_module_d000) = { "l4-wkup-clkctrl@0_bc" }; /* adc_tsc */
+PLIST(target_module_31000) = { "l4-wkup-clkctrl@0_c4" }; /* timer1 */
+PLIST(target_module_35000) = { "l4-wkup-clkctrl@0_d4" }; /* timer2 */
+
+PLIST(target_module_3e000) = { "l4-rtc-clkctrl@0_0" }; /* rtc */
+
+PLIST(target_module_100000) = {
+	"cpsw-125mhz-clkctrl@0_14"
+}; /* cpsw (ethernet) */
+
+PLIST(target_module_300000) = { "pruss-ocp-clkctrl@e8_0" }; /* pru */
+
+PLIST(target_module_22000) = { "l4ls-clkctrl@38_34" }; /* uart2 */
+PLIST(target_module_24000) = { "l4ls-clkctrl@38_38" }; /* uart3 */
+PLIST(target_module_2a000) = { "l4ls-clkctrl@38_10" }; /* i2c2 */
+PLIST(target_module_30000) = { "l4ls-clkctrl@38_14" }; /* spi0 */
+
+PLIST(target_module_40000) = { "l4ls-clkctrl@38_48" }; /* timer2 */
+PLIST(target_module_42000) = { "l4ls-clkctrl@38_4c" }; /* timer3 */
+PLIST(target_module_44000) = { "l4ls-clkctrl@38_50" }; /* timer4 */
+PLIST(target_module_46000) = { "l4ls-clkctrl@38_b4" }; /* timer5 */
+PLIST(target_module_48000) = { "l4ls-clkctrl@38_b8" }; /* timer6 */
+PLIST(target_module_4a000) = { "l4ls-clkctrl@38_44" }; /* timer7 */
+PLIST(target_module_4c000) = {
+	"l4ls-clkctrl@38_74",
+	"l4ls-clkctrl@38_75"
+}; /* gpio2 */
+PLIST(target_module_60000) = { "l4ls-clkctrl@38_4" }; /* mmc1 */
+PLIST(target_module_80000) = { "l4ls-clkctrl@38_8" }; /* elm */
+PLIST(target_module_c8000) = { "l4ls-clkctrl@38_d8" }; /* mailbox */
+PLIST(target_module_ca000) = { "l4ls-clkctrl@38_d4" }; /* spinlock */
+PLIST(target_module_9c000) = { "l4ls-clkctrl@38_c" }; /* i2c3 */
+PLIST(target_module_a0000) = { "l4ls-clkctrl@38_18" }; /* spi1 */
+PLIST(target_module_a6000) = { "l4ls-clkctrl@38_3c" }; /* uart4 */
+PLIST(target_module_a8000) = { "l4ls-clkctrl@38_40" }; /* uart5 */
+PLIST(target_module_aa000) = { "l4ls-clkctrl@38_0" }; /* uart6 */
+PLIST(target_module_ac000) = {
+	"l4ls-clkctrl@38_78",
+	"l4ls-clkctrl@38_79"
+}; /* gpio3 */
+PLIST(target_module_ae000) = {
+	"l4ls-clkctrl@38_7c",
+	"l4ls-clkctrl@38_7d"
+}; /* gpio4 */
+PLIST(target_module_cc000) = { "l4ls-clkctrl@38_88" }; /* dcan0 */
+PLIST(target_module_d0000) = { "l4ls-clkctrl@38_8c" }; /* dcan1 */
+PLIST(target_module_d8000) = { "l4ls-clkctrl@38_bc" }; /* mmc2 */
+PLIST(target_module_0) = { "l4ls-clkctrl@38_9c" }; /* epwmss0 */
+PLIST(target_module_2000) = { "l4ls-clkctrl@38_94" }; /* epwmss1 */
+PLIST(target_module_4000) = { "l4ls-clkctrl@38_a0" }; /* epwmss2 */
+
+PLIST(target_module_e000) = { "lcdc-clkctrl@18_0" }; /* lcdc */
+
+PLIST(target_module_10000) = { "l4ls-clkctrl@38_58" }; /* rng */
+
+PLIST(target_module_49800000) = { "l3-clkctrl@24_0" }; /* tptco */
+PLIST(target_module_4c000000) = { "l3-clkctrl@24_4" }; /* emif */
+PLIST(target_module_40300000) = { "l3-clkctrl@24_8" }; /* ocmcram */
+PLIST(target_module_53500000) = { "l3-clkctrl@24_70" }; /* aes */
+PLIST(target_module_53100000) = { "l3-clkctrl@24_7c" }; /* sham */
+
+PLIST(target_module_49000000) = { "l3-clkctrl@24_98" }; /* tpcc */
+PLIST(target_module_4b000000) = { "l3-clkctrl@24_b8" }; /* l3 instr */
+PLIST(target_module_49900000) = { "l3-clkctrl@24_d8" }; /* tptc1 */
+PLIST(target_module_49a00000) = { "l3-clkctrl@24_dc" }; /* tptc2 */
+
+PLIST(target_module_47400000) = { "l3s-clkctrl@1c_0" }; /* usb otg hs */
+PLIST(target_module_50000000) = { "l3s-clkctrl@1c_14" }; /* gpmc */
+PLIST(target_module_38000) = { "l3s-clkctrl@1c_18" }; /* mcasp0 */
+PLIST(target_module_3c000) = { "l3s-clkctrl@1c_4c" }; /* mcasp1 */
+PLIST(target_module_47810000) = { "l3s-clkctrl@1c_dc" }; /* mmc3 */
+PLIST(target_module_140000) = { "l3-aon-clkctrl@14_0" }; /* l3 debugss */
+PLIST(target_module_56000000) = { "gfx-l3-clkctrl@0_4" }; /* gfx */
+
+
+static struct parent_lookup_table sysc_clock_table[] = {
+{
+	"target-module@7000",
+	nitems(target_module_7000),
+	target_module_7000
+},
+{
+	"target-module@9000",
+	nitems(target_module_9000),
+	target_module_9000
+},
+{
+	"target-module@b000",
+	nitems(target_module_b000),
+	target_module_b000
+},
+{
+	"target-module@d000",
+	nitems(target_module_d000),
+	target_module_d000
+},
+{
+	"target-module@31000",
+	nitems(target_module_31000),
+	target_module_31000
+},
+{
+	"target-module@35000",
+	nitems(target_module_35000),
+	target_module_35000
+},
+
+{
+	"target-module@3e000",
+	nitems(target_module_3e000),
+	target_module_3e000
+},
+
+{
+	"target-module@100000",
+	nitems(target_module_100000),
+	target_module_100000
+},
+{
+	"target-module@300000",
+	nitems(target_module_300000),
+	target_module_300000
+},
+{
+	"target-module@22000",
+	nitems(target_module_22000),
+	target_module_22000
+},
+{
+	"target-module@24000",
+	nitems(target_module_24000),
+	target_module_24000
+},
+{
+	"target-module@2a000",
+	nitems(target_module_2a000),
+	target_module_2a000
+},
+{
+	"target-module@30000",
+	nitems(target_module_30000),
+	target_module_30000
+},
+{
+	"target-module@40000",
+	nitems(target_module_40000),
+	target_module_40000
+},
+{
+	"target-module@42000",
+	nitems(target_module_42000),
+	target_module_42000
+},
+{
+	"target-module@44000",
+	nitems(target_module_44000),
+	target_module_44000
+},
+{
+	"target-module@46000",
+	nitems(target_module_46000),
+	target_module_46000
+},
+{
+	"target-module@48000",
+	nitems(target_module_48000),
+	target_module_48000
+},
+{
+	"target-module@4a000",
+	nitems(target_module_4a000),
+	target_module_4a000
+},
+{
+	"target-module@4c000",
+	nitems(target_module_4c000),
+	target_module_4c000
+},
+{
+	"target-module@60000",
+	nitems(target_module_60000),
+	target_module_60000
+},
+{
+	"target-module@80000",
+	nitems(target_module_80000),
+	target_module_80000
+},
+{
+	"target-module@c8000",
+	nitems(target_module_c8000),
+	target_module_c8000
+},
+{
+	"target-module@ca000",
+	nitems(target_module_ca000),
+	target_module_ca000
+},
+{
+	"target-module@9c000",
+	nitems(target_module_9c000),
+	target_module_9c000
+},
+{
+	"target-module@a0000",
+	nitems(target_module_a0000),
+	target_module_a0000
+},
+{
+	"target-module@a6000",
+	nitems(target_module_a6000),
+	target_module_a6000
+},
+{
+	"target-module@a8000",
+	nitems(target_module_a8000),
+	target_module_a8000
+},
+{
+	"target-module@aa000",
+	nitems(target_module_aa000),
+	target_module_aa000
+},
+{
+	"target-module@ac000",
+	nitems(target_module_ac000),
+	target_module_ac000
+},
+{
+	"target-module@ae000",
+	nitems(target_module_ae000),
+	target_module_ae000
+},
+{
+	"target-module@cc000",
+	nitems(target_module_cc000),
+	target_module_cc000
+},
+{
+	"target-module@d0000",
+	nitems(target_module_d0000),
+	target_module_d0000
+},
+{
+	"target-module@d8000",
+	nitems(target_module_d8000),
+	target_module_d8000
+},
+{
+	"target-module@0",
+	nitems(target_module_0),
+	target_module_0
+},
+{
+	"target-module@2000",
+	nitems(target_module_2000),
+	target_module_2000
+},
+{
+	"target-module@4000",
+	nitems(target_module_4000),
+	target_module_4000
+},
+{
+	"target-module@e000",
+	nitems(target_module_e000),
+	target_module_e000
+},
+{
+	"target-module@10000",
+	nitems(target_module_10000),
+	target_module_10000
+},
+{
+	"target-module@49000000",
+	nitems(target_module_49000000),
+	target_module_49000000
+},
+{
+	"target-module@49800000",
+	nitems(target_module_49800000),
+	target_module_49800000
+},
+{
+	"target-module@4c000000",
+	nitems(target_module_4c000000),
+	target_module_4c000000
+},
+{
+	"target-module@40300000",
+	nitems(target_module_40300000),
+	target_module_40300000
+},
+{
+	"target-module@49900000",
+	nitems(target_module_49900000),
+	target_module_49900000
+},
+{
+	"target-module@49a00000",
+	nitems(target_module_49a00000),
+	target_module_49a00000
+},
+{
+	"target-module@47810000",
+	nitems(target_module_47810000),
+	target_module_47810000
+},
+{
+	"target-module@47400000",
+	nitems(target_module_47400000),
+	target_module_47400000
+},
+{
+	"target-module@50000000",
+	nitems(target_module_50000000),
+	target_module_50000000
+},
+{
+	"target-module@38000",
+	nitems(target_module_38000),
+	target_module_38000
+},
+{
+	"target-module@3c000",
+	nitems(target_module_3c000),
+	target_module_3c000
+},
+{
+	"target-module@4b000000",
+	nitems(target_module_4b000000),
+	target_module_4b000000
+},
+{
+	"target-module@140000",
+	nitems(target_module_140000),
+	target_module_140000
+},
+{
+	"target-module@53100000",
+	nitems(target_module_53100000),
+	target_module_53100000
+},
+{
+	"target-module@53500000",
+	nitems(target_module_53500000),
+	target_module_53500000
+},
+{
+	"target-module@56000000",
+	nitems(target_module_56000000),
+	target_module_56000000
+},
+};
+
+static struct clk_link_def scm_clocks[] = {
+	LINK("sys_clkin_ck"),
+	LINK("adc_tsc_fck"),
+	LINK("dcan0_fck"),
+	LINK("dcan1_fck"),
+	LINK("mcasp0_fck"),
+	LINK("mcasp1_fck"),
+	LINK("smartreflex0_fck"),
+	LINK("smartreflex1_fck"),
+	LINK("sha0_fck"),
+	LINK("aes0_fck"),
+	LINK("rng_fck"),
+	LINK("ehrpwm0_tbclk"),
+	LINK("ehrpwm1_tbclk"),
+	LINK("ehrpwm2_tbclk"),
+};
+
+static struct clk_link_def per_cm_0[] = {
+	/* reg = <0x38 0x2c>, <0x6c 0x28>, <0xac 0xc>,
+		 <0xc0 0x1c>, <0xec 0xc>, <0x10c 0x8>, <0x130 0x4>; */
+	/* <0x38 0x2c> */
+	LINK("l4ls-clkctrl@38_0"),
+	LINK("l4ls-clkctrl@38_4"),
+	LINK("l4ls-clkctrl@38_8"),
+	LINK("l4ls-clkctrl@38_c"),
+	LINK("l4ls-clkctrl@38_10"),
+	LINK("l4ls-clkctrl@38_14"),
+	LINK("l4ls-clkctrl@38_18"),
+	LINK("l4ls-clkctrl@38_1c"),
+	LINK("l4ls-clkctrl@38_20"),
+	LINK("l4ls-clkctrl@38_24"),
+	LINK("l4ls-clkctrl@38_28"),
+	/* <0x6c 0x28> */
+	LINK("l4ls-clkctrl@38_34"),
+	LINK("l4ls-clkctrl@38_38"),
+	LINK("l4ls-clkctrl@38_3c"),
+	LINK("l4ls-clkctrl@38_40"),
+	LINK("l4ls-clkctrl@38_44"),
+	LINK("l4ls-clkctrl@38_48"),
+	LINK("l4ls-clkctrl@38_4c"),
+	LINK("l4ls-clkctrl@38_50"),
+	LINK("l4ls-clkctrl@38_54"),
+	LINK("l4ls-clkctrl@38_58"),
+	/* <0xac 0xc> */
+	LINK("l4ls-clkctrl@38_74"),
+	LINK("l4ls-clkctrl@38_75"),
+	LINK("l4ls-clkctrl@38_78"),
+	LINK("l4ls-clkctrl@38_79"),
+	LINK("l4ls-clkctrl@38_7c"),
+	LINK("l4ls-clkctrl@38_7d"),
+	/* <0xc0 0x1c> */
+	LINK("l4ls-clkctrl@38_88"),
+	LINK("l4ls-clkctrl@38_8c"),
+	LINK("l4ls-clkctrl@38_90"),
+	LINK("l4ls-clkctrl@38_94"),
+	LINK("l4ls-clkctrl@38_98"),
+	LINK("l4ls-clkctrl@38_9c"),
+	LINK("l4ls-clkctrl@38_a0"),
+	/* <0xec 0xc> */
+	LINK("l4ls-clkctrl@38_b4"),
+	LINK("l4ls-clkctrl@38_b8"),
+	LINK("l4ls-clkctrl@38_bc"),
+	/* <0xd4 0x8> */
+	LINK("l4ls-clkctrl@38_d4"),
+	LINK("l4ls-clkctrl@38_d8"),
+	/* <0x130 0x4> */
+	LINK("l4ls-clkctrl@38_f8"),
+
+	/* reg = <0x1c 0x4>, <0x30 0x8>, <0x68 0x4>, <0xf8 0x4> */
+	/* <0x1c 0x4> */
+	LINK("l3s-clkctrl@1c_0"),
+	/* <0x30 0x8> */
+	LINK("l3s-clkctrl@1c_14"),
+	LINK("l3s-clkctrl@1c_18"),
+	/* <0x68 0x4> */
+	LINK("l3s-clkctrl@1c_4c"),
+	/* <0xf8 0x4> */
+	LINK("l3s-clkctrl@1c_dc"),
+
+
+	/* reg = <0x24 0xc>, <0x94 0x10>, <0xbc 0x4>, <0xdc 0x8>, <0xfc 0x8>; */
+	/* <0x24 0xc> */
+	LINK("l3-clkctrl@24_0"),
+	LINK("l3-clkctrl@24_4"),
+	LINK("l3-clkctrl@24_8"),
+	/* <0x94 0x10> */
+	LINK("l3-clkctrl@24_70"),
+	LINK("l3-clkctrl@24_74"),
+	LINK("l3-clkctrl@24_78"),
+	LINK("l3-clkctrl@24_7c"),
+	/* <0xbc 0x4> */
+	LINK("l3-clkctrl@24_98"),
+	/* <0xdc 0x8> */
+	LINK("l3-clkctrl@24_b8"),
+	LINK("l3-clkctrl@24_bc"),
+	/* <0xfc 0x8> */
+	LINK("l3-clkctrl@24_d8"),
+	LINK("l3-clkctrl@24_dc"),
+
+	/* reg = <0x120 0x4>; */
+	LINK("l4hs-clkctrl@120_0"),
+
+	/* reg = <0xe8 0x4>; */
+	LINK("pruss-ocp-clkctrl@e8_0"),
+
+	/* reg = <0x0 0x18>; */
+	LINK("cpsw-125mhz-clkctrl@0_0"),
+	LINK("cpsw-125mhz-clkctrl@0_4"),
+	LINK("cpsw-125mhz-clkctrl@0_8"),
+	LINK("cpsw-125mhz-clkctrl@0_c"),
+	LINK("cpsw-125mhz-clkctrl@0_10"),
+	LINK("cpsw-125mhz-clkctrl@0_14"),
+
+	/* reg = <0x18 0x4>; */
+	LINK("lcdc-clkctrl@18_0"),
+
+	/* reg = <0x14c 0x4>; */
+	LINK("clk-24mhz-clkctrl@14c_0"),
+
+	/* reg = <0x0 0x10>, <0xb4 0x24>; */
+	/* <0x0 0x10> */
+	LINK("l4-wkup-clkctrl@0_0"),
+	LINK("l4-wkup-clkctrl@0_4"),
+	LINK("l4-wkup-clkctrl@0_8"),
+	LINK("l4-wkup-clkctrl@0_9"),
+	LINK("l4-wkup-clkctrl@0_c"),
+	/* <0xb4 0x24> */
+	LINK("l4-wkup-clkctrl@0_b4"),
+	LINK("l4-wkup-clkctrl@0_b8"),
+	LINK("l4-wkup-clkctrl@0_bc"),
+	LINK("l4-wkup-clkctrl@0_c0"),
+	LINK("l4-wkup-clkctrl@0_c4"),
+	LINK("l4-wkup-clkctrl@0_c8"),
+	LINK("l4-wkup-clkctrl@0_cc"),
+	LINK("l4-wkup-clkctrl@0_d0"),
+	LINK("l4-wkup-clkctrl@0_d4"),
+
+	/* reg = <0x14 0x4>; */
+	LINK("l3-aon-clkctrl@14_0"),
+
+	/* reg = <0xb0 0x4>; */
+	LINK("l4-wkup-aon-clkctrl@b0_0"),
+
+	/* reg = <0x0 0x8>; */
+	LINK("mpu-clkctrl@0_0"),
+	LINK("mpu-clkctrl@0_4"),
+
+	/* reg = <0x0 0x4>; */
+	LINK("l4-rtc-clkctrl@0_0"),
+
+	/* reg = <0x0 0x8>; */
+	LINK("gfx-l3-clkctrl@0_0"),
+	LINK("gfx-l3-clkctrl@0_4"),
+
+	/* reg = <0x0 0x24>; */
+	LINK("l4-cefuse-clkctrl@0_0"),
+	LINK("l4-cefuse-clkctrl@0_4"),
+	LINK("l4-cefuse-clkctrl@0_8"),
+	LINK("l4-cefuse-clkctrl@0_c"),
+	LINK("l4-cefuse-clkctrl@0_10"),
+	LINK("l4-cefuse-clkctrl@0_14"),
+	LINK("l4-cefuse-clkctrl@0_18"),
+	LINK("l4-cefuse-clkctrl@0_1c"),
+	LINK("l4-cefuse-clkctrl@0_20"),
+};
+
+/* === ti_clkctrl.c === */
+/*
+ * Check out XX_CLKCTRL-INDEX(offset)-macro dance in
+ * sys/gnu/dts/dts/include/dt-bindings/clock/am3.h
+ * sys/gnu/dts/dts/include/dt-bindings/clock/am4.h
+ * sys/gnu/dts/dts/include/dt-bindings/clock/dra7.h
+ * it is the basis for the name scheme
+ * xxx_clkctrl_[baseoffset]_[offset from base]
+ */
+
+/* reg = <0x38 0x2c>, <0x6c 0x28>, <0xac 0xc>, <0xc0 0x1c>, <0xec 0xc>, <0x10c 0x8>, <0x130 0x4>; */
+/* <0x38 0x2c> */
+PLIST(l4ls_clkctrl_38_0) = { "dpll_per_m2_div4_ck" }; /* am3.h UART6 clkctrl, TRM 19.2.2 */
+PLIST(l4ls_clkctrl_38_4) = { "mmc_clk" }; /* am3.h MMC1 clkctrl, TRM 18.2.2 */
+PLIST(l4ls_clkctrl_38_8) = { "l4ls_gclk" }; /* am3.h ELM clkctrl, TRM 7.4.2.2 */
+PLIST(l4ls_clkctrl_38_c) = { "dpll_per_m2_div4_ck" }; /* am3.h I2C3 clkctrl, TRM 21.2.2 */
+PLIST(l4ls_clkctrl_38_10) = { "dpll_per_m2_div4_ck" }; /* am3.h I2C2 clkctrl, TRM 21.2.2 */
+PLIST(l4ls_clkctrl_38_14) = { "dpll_per_m2_div4_ck" }; /* am3.h SPI0 clkctrl, TRM 24.2.2 */
+PLIST(l4ls_clkctrl_38_18) = { "dpll_per_m2_div4_ck" }; /* am3.h SPI1 clkctrl, TRM 24.2.2 */
+/* 1c, 20, 24 are not described in the TRM */
+//PLIST(l4ls_clkctrl_38_1c) = { NULL }; /* am3.h TRM ? */
+//PLIST(l4ls_clkctrl_38_20) = { NULL }; /* am3.h TRM ? */
+//PLIST(l4ls_clkctrl_38_24) = { NULL }; /* am3.h TRM ? */
+PLIST(l4ls_clkctrl_38_28) = { "l4ls_gclk" }; /* am3.h L4_LS clkctrl, TRM 8.1.12.1.19 */
+/* <0x6c 0x28> */
+PLIST(l4ls_clkctrl_38_34) = { "dpll_per_m2_div4_ck" }; /* am3.h UART2 clkctrl, TRM 19.2.2 */
+PLIST(l4ls_clkctrl_38_38) = { "dpll_per_m2_div4_ck" }; /* am3.h UART3 clkctrl, TRM 19.2.2 */
+PLIST(l4ls_clkctrl_38_3c) = { "dpll_per_m2_div4_ck" }; /* am3.h UART4 clkctrl, TRM 19.2.2 */
+PLIST(l4ls_clkctrl_38_40) = { "dpll_per_m2_div4_ck" }; /* am3.h UART5 clkctrl, TRM 19.2.2 */
+PLIST(l4ls_clkctrl_38_44) = { "timer7_fck" }; /* am3.h TIMER7 clkctrl, TRM 20.1.2.3 */
+PLIST(l4ls_clkctrl_38_48) = { "timer2_fck" }; /* am3.h TIMER7 clkctrl, TRM 20.1.2.3 */
+PLIST(l4ls_clkctrl_38_4c) = { "timer3_fck" }; /* am3.h TIMER2 clkctrl, TRM 20.1.2.3 */
+PLIST(l4ls_clkctrl_38_50) = { "timer4_fck" }; /* am3.h TIMER3 clkctrl, TRM 20.1.2.3 */
+//PLIST(l4ls_clkctrl_38_54) = { NULL }; /* am3.h ? TRM ? */
+PLIST(l4ls_clkctrl_38_58) = { "rng_fck" }; /* am3.h RNG clkctrl, TRM doesnt describe the rng, rng_fck only from the am33xx-clocks.dtsi */
+/* <0xac 0xc> */
+PLIST(l4ls_clkctrl_38_74) = { "l4ls_gclk" }; /* am3.h GPIO2 clkctrl, TRM 25.2.2 */
+PLIST(l4ls_clkctrl_38_75) = { "clk_32768_ck" }; /* am3.h GPIO2 clkctrl, TRM 25.2.2 */
+PLIST(l4ls_clkctrl_38_78) = { "l4ls_gclk" }; /* am3.h GPIO3 clkctrl, TRM 25.2.2 */
+PLIST(l4ls_clkctrl_38_79) = { "clk_32768_ck" }; /* am3.h GPIO3 clkctrl, TRM 25.2.2 */
+PLIST(l4ls_clkctrl_38_7c) = { "l4ls_gclk" }; /* am3.h GPIO4 clkctrl, TRM 25.2.2 */
+PLIST(l4ls_clkctrl_38_7d) = { "clk_32768_ck" }; /* am3.h GPIO4 clkctrl, TRM 25.2.2 */
+/* <0xc0 0x1c> */
+PLIST(l4ls_clkctrl_38_88) = { "dcan0_fck" }; /* am3.h D_CAN0 clkctrl, TRM 23.2.2 */
+PLIST(l4ls_clkctrl_38_8c) = { "dcan1_fck" }; /* am3.h D_CAN1 clkctrl, TRM 23.2.2 */
+/* 90 not described in am3.h */
+//PLIST(l4ls_clkctrl_38_90) = { NULL }; /* am3.h */
+PLIST(l4ls_clkctrl_38_94) = { "l4ls_gclk" }; /* am3.h EPWMMS1 clkctrl, TRM 15.1.2.3 */
+/* 98 not described in am3.h */
+//PLIST(l4ls_clkctrl_38_98) = { NULL }; /* am3.h */
+PLIST(l4ls_clkctrl_38_9c) = { "l4ls_gclk" }; /* am3.h EPWMMS0 clkctrl, TRM 15.1.2.3 */
+PLIST(l4ls_clkctrl_38_a0) = { "l4ls_gclk" }; /* am3.h EPWMMS2 clkctrl, TRM 15.1.2.3 */
+/* <0xec 0xc> */
+PLIST(l4ls_clkctrl_38_b4) = { "timer5_fck" }; /* am3.h TIMER5 clkctrl, TRM 20.1.2.3 */
+PLIST(l4ls_clkctrl_38_b8) = { "timer6_fck" }; /* am3.h TIMER6 clkctrl, TRM 20.1.2.3 */
+PLIST(l4ls_clkctrl_38_bc) = { "mmc_clk" }; /* am3.h MMC2 clkctrl, TRM 18.2.2 */
+/* <0xd4 0x8> */
+PLIST(l4ls_clkctrl_38_d4) = { "l4ls_gclk" }; /* am3.h SPINLOCK clkctrl, TRM 8.1.12.1.48 "SPINLOCK clocks" */
+PLIST(l4ls_clkctrl_38_d8) = { "l4ls_gclk" }; /* am3.h MAILBOX clkctrl, TRM 17.1.1.2 */
+/* <0x130 0x4> */
+PLIST(l4ls_clkctrl_38_f8) = { "l4ls_gclk" }; /* am3.h OCPWP clkctrl, TRM 8.1.12.1.53 "OCPWP clocks" */
+
+/* reg = <0x1c 0x4>, <0x30 0x8>, <0x68 0x4>, <0xf8 0x4> */
+/* <0x1c 0x4> */
+PLIST(l3s_clkctrl_1c_0) = { "usbotg_fck" }; /* am3.h USB_OTG_HS clkctrl, TRM 16.1.2 fig 16-1 */
+/* <0x30 0x8> */
+PLIST(l3s_clkctrl_1c_14) = { "l3s_gclk" }; /* am3.h GPMC clkctrl, TRM 7.1.2.2 */
+PLIST(l3s_clkctrl_1c_18) = { "mcasp0_fck" }; /* am3.h MCASP0 clkctrl, TRM 22.2.2 */
+/* <0x68 0x4> */
+PLIST(l3s_clkctrl_1c_4c) = { "mcasp1_fck" }; /* am3.h MCASP1 clkctrl, TRM 22.2.2 */
+/* <0xf8 0x4> */
+PLIST(l3s_clkctrl_1c_dc) = { "mmc_clk" }; /* am3.h MMC3 clkctrl, TRM 18.2.2 */
+
+/* reg = <0x24 0xc>, <0x94 0x10>, <0xbc 0x4>, <0xdc 0x8>, <0xfc 0x8>; */
+/* <0x24 0xc> */
+PLIST(l3_clkctrl_24_0) = { "l3_gclk" }; /* am3.h TPTC0 clkctrl, TRM 11.2.2.2 */
+PLIST(l3_clkctrl_24_4) = { "dpll_ddr_m2_div2_ck" }; /* am3.h EMIF clkctrl, TRM 7.3.2.2 */
+PLIST(l3_clkctrl_24_8) = { "l3_gclk" }; /* am3.h OCMCRAM clkctrl, TRM 7.2.2.2 */
+/* <0x94 0x10> */
+PLIST(l3_clkctrl_24_70) = { "aes0_fck" }; /* am3.h AES clkctrl, not in TRM, derived from am33xx-clocks.dtsi */
+//PLIST(l3_clkctrl_24_74) = { NULL }; /* am3.h ?? clkctrl, TRM ??? */
+//PLIST(l3_clkctrl_24_78) = { NULL }; /* am3.h ?? clkctrl, TRM ???? */
+PLIST(l3_clkctrl_24_7c) = { "l3_gclk" }; /* am3.h SHAM clkctrl, not in TRM, assume l3_gclk */
+/* <0xbc 0x4> */
+PLIST(l3_clkctrl_24_98) = { "l3_gclk" }; /* am3.h TPCC clkctrl, TRM 11.2.1.2 */
+/* <0xdc 0x8> */
+PLIST(l3_clkctrl_24_b8) = { "l3_gclk" }; /* am3.h L3 INSTR clkctrl, TRM 8.1.12.1.38 "L3 INSTR clocks" */
+PLIST(l3_clkctrl_24_bc) = { "l3_gclk" }; /* am3.h L3 Main clkctrl, TRM 18.1.12.1.39 "L3 interconnect clocks" */
+/* <0xfc 0x8> */
+PLIST(l3_clkctrl_24_d8) = { "l3_gclk" }; /* am3.h TPTC1 clkctrl, TRM 11.2.2.2 */
+PLIST(l3_clkctrl_24_dc) = { "l3_gclk" }; /* am3.h TPTC2 clkctrl, TRM 11.2.2.2 */
+
+/* reg = <0x120 0x4>; */
+PLIST(l4hs_clkctrl_120_0) = { "l4hs_gclk" }; /* am3.h L4HS clkctrl, TRM 8.1.12.1.50 */
+
+/* reg = <0xe8 0x4>; */
+PLIST(pruss_ocp_clkctrl_e8_0) = { "pruss_ocp_gclk" }; /* am3.h ocp pruss clkctrl, TRM 4.2.2 */
+
+/* reg = <0x0 0x18>; */
+#if 0
+PLIST(cpsw_125mhz_clkctrl_0_0) = { NULL }; /* am3.h Not mentioned in TRM, TRM 14.2.2 */
+PLIST(cpsw_125mhz_clkctrl_0_4) = { NULL }; /* am3.h Not mentioned in TRM, TRM 14.2.2 */
+PLIST(cpsw_125mhz_clkctrl_0_8) = { NULL }; /* am3.h Not mentioned in TRM, TRM 14.2.2 */
+PLIST(cpsw_125mhz_clkctrl_0_c) = { NULL }; /* am3.h Not mentioned in TRM, TRM 14.2.2 */
+PLIST(cpsw_125mhz_clkctrl_0_10) = { NULL }; /* am3.h Not mentioned in TRM, TRM 14.2.2 */
+#endif
+PLIST(cpsw_125mhz_clkctrl_0_14) = { "cpsw_125mhz_gclk" }; /* am3.h cpsw 125 mhz cpgmaco clkctrl, TRM 14.2.2 */
+
+/* reg = <0x18 0x4>; */
+PLIST(lcdc_clkctrl_18_0) = { "lcd_gclk" }; /* am3.h lcdc clkctrl, TRM 13.2.2 */
+
+/* reg = <0x14c 0x4>; */
+PLIST(clk_24mhz_clkctrl_14c_0) = { "clkdiv32k_ck" }; /* am3.h clkdiv32k clkctrl, TRM 8.1.12.1.57 */
+
+/* reg = <0x0 0x10>, <0xb4 0x24>; */
+/* <0x0 0x10> */
+//PLIST(l4_wkup_clkctrl_0_0) = { NULL }; /* am3.h clkstctrl, TRM 8.1.12.2.1 */
+PLIST(l4_wkup_clkctrl_0_4) = { "mmc_clk" }; /* am3.h control clkctrl, TRM 18.2.2 */
+PLIST(l4_wkup_clkctrl_0_8) = { "dpll_core_m4_div2_ck" }; /* am3.h gpio1 clkctrl, TRM 25.2.2 */
+PLIST(l4_wkup_clkctrl_0_9) = { "gpio0_dbclk_mux_ck" }; /* am3.h gpio1 clkctrl, TRM 25.2.2 */
+PLIST(l4_wkup_clkctrl_0_c) = { "mmc_clk" }; /* am3.h L4 wkup clkctrl, TRM 18.2.2 */
+/* <0xb4 0x24> */
+PLIST(l4_wkup_clkctrl_0_b4) = { "dpll_per_m2_div4_wkupdm_ck" }; /* am3.h uart1 clkctrl, TRM 19.2.2 */
+PLIST(l4_wkup_clkctrl_0_b8) = { "dpll_per_m2_div4_wkupdm_ck" }; /* am3.h i2c1 wkup clkctrl, TRM 21.2.2 */
+PLIST(l4_wkup_clkctrl_0_bc) = { "adc_tsc_fck" }; /* am3.h adc tsc clkctrl, TRM 12.2.2 */
+PLIST(l4_wkup_clkctrl_0_c0) = { "smartreflex0_fck" }; /* am3.h smartreflex0 clkctrl, TRM 8.1.12.2.49 */
+PLIST(l4_wkup_clkctrl_0_c4) = { "timer1_fck" }; /* am3.h timer1 clkctrl, TRM 20.1.2.3 */
+PLIST(l4_wkup_clkctrl_0_c8) = { "smartreflex1_fck" }; /* am3.h smartreflex1 clkctrl, TRM 8.1.12.2.51 */
+//PLIST(l4_wkup_clkctrl_0_cc) = { NULL }; /* am3.h l4_wkup_aon_clkstctrl, TRM 8.1.12.2.52 */
+//PLIST(l4_wkup_clkctrl_0_d0) = { NULL }; /* am3.h ??? clkctrl, not in TRM */
+PLIST(l4_wkup_clkctrl_0_d4) = { "wdt1_fck" }; /* am3.h wd timer2 clkctrl, TRM 20.4.2.2 */
+
+/* reg = <0x14 0x4>; */
+//PLIST(l3_aon_clkctrl_14_0) = { NULL }; /* am3.h debugss clkctrl, TRM 8.1.12.2.6 multiple sub clocks - todo */
+
+/* reg = <0xb0 0x4>; */
+//PLIST(l4_wkup_aon_wkup_m3_clkctrl_b0_0) = { NULL }; /* am3.h l4 wkup aon wkup m3 clkctrl, TRM 8.1.12.2.45 */
+
+/* reg = <0x0 0x8>; */
+//PLIST(mpu_clkctrl_0_0) = { NULL }; /* am3.h mpu clkstctrl, TRM 8.1.12.4.1 */
+PLIST(mpu_clkctrl_0_4) = { "dpll_mpu_ck" }; /* am3.h mpu clkctrl, TRM 8.1.12.4.2 / 3.1.3 */
+
+/* reg = <0x0 0x4>; */
+PLIST(l4_rtc_clkctrl_0_0) = { "clk_32768_ck" }; /* am3.h RTC clkctrl, TRM 20.3.2.2 */
+
+/* reg = <0x0 0x8>; */
+//PLIST(gfx_l3_clkctrl_0_0) = { NULL }; /* am3.h L3 GFX clkctrl, TRM 5.1.2 */
+PLIST(gfx_l3_clkctrl_0_4) = { "gfx_fck_div_ck" }; /* am3.h L3 GFX clkctrl, TRM 5.1.2 */
+
+/* reg = <0x0 0x24>; */
+#if 0
+PLIST(l4_cefuse_clkctrl_0_0) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2  */
+PLIST(l4_cefuse_clkctrl_0_4) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2  */
+PLIST(l4_cefuse_clkctrl_0_8) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2  */
+PLIST(l4_cefuse_clkctrl_0_c) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2  */
+PLIST(l4_cefuse_clkctrl_0_10) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2  */
+PLIST(l4_cefuse_clkctrl_0_14) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2  */
+PLIST(l4_cefuse_clkctrl_0_18) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2  */
+PLIST(l4_cefuse_clkctrl_0_1c) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2  */
+PLIST(l4_cefuse_clkctrl_0_20) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2  */
+#endif
+
+
+static struct ti_clkctrl_lookup_table am33xx_l4ls_clkctrl_table[] = {
+
+/* reg = <0x38 0x2c>, <0x6c 0x28>, <0xac 0xc>, <0xc0 0x1c>, <0xec 0xc>, <0x10c 0x8>, <0x130 0x4>;
+	*/
+/* <0x38 0x2c> */
+	{ "l4ls-clkctrl@38_0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_UART6_CLKCTRL, 0, nitems(l4ls_clkctrl_38_0), l4ls_clkctrl_38_0 },
+	{ "l4ls-clkctrl@38_4", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_MMC1_CLKCTRL, 0, nitems(l4ls_clkctrl_38_4), l4ls_clkctrl_38_4 },
+	{ "l4ls-clkctrl@38_8", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_ELM_CLKCTRL, 0, nitems(l4ls_clkctrl_38_8), l4ls_clkctrl_38_8 },
+	{ "l4ls-clkctrl@38_c", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_I2C3_CLKCTRL, 0, nitems(l4ls_clkctrl_38_c), l4ls_clkctrl_38_c },
+	{ "l4ls-clkctrl@38_10", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_I2C2_CLKCTRL, 0, nitems(l4ls_clkctrl_38_10), l4ls_clkctrl_38_10 },
+	{ "l4ls-clkctrl@38_14", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_SPI0_CLKCTRL, 0, nitems(l4ls_clkctrl_38_14), l4ls_clkctrl_38_14 },
+	{ "l4ls-clkctrl@38_18", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_SPI1_CLKCTRL, 0, nitems(l4ls_clkctrl_38_18), l4ls_clkctrl_38_18 },
+	{ "l4ls-clkctrl@38_1c", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4ls-clkctrl@38_20", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4ls-clkctrl@38_24", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4ls-clkctrl@38_28", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_L4_LS_CLKCTRL, 0, nitems(l4ls_clkctrl_38_28), l4ls_clkctrl_38_28 },
+/* <0x6c 0x28> */
+	{ "l4ls-clkctrl@38_34", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_UART2_CLKCTRL, 0, nitems(l4ls_clkctrl_38_34), l4ls_clkctrl_38_34 },
+	{ "l4ls-clkctrl@38_38", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_UART3_CLKCTRL, 0, nitems(l4ls_clkctrl_38_38), l4ls_clkctrl_38_38 },
+	{ "l4ls-clkctrl@38_3c", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_UART4_CLKCTRL, 0, nitems(l4ls_clkctrl_38_3c), l4ls_clkctrl_38_3c },
+	{ "l4ls-clkctrl@38_40", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_UART5_CLKCTRL, 0, nitems(l4ls_clkctrl_38_40), l4ls_clkctrl_38_40 },
+	{ "l4ls-clkctrl@38_44", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_TIMER7_CLKCTRL, 0, nitems(l4ls_clkctrl_38_44), l4ls_clkctrl_38_44 },
+	{ "l4ls-clkctrl@38_48", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_TIMER2_CLKCTRL, 0, nitems(l4ls_clkctrl_38_48), l4ls_clkctrl_38_48 },
+	{ "l4ls-clkctrl@38_4c", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_TIMER3_CLKCTRL, 0, nitems(l4ls_clkctrl_38_4c), l4ls_clkctrl_38_4c },
+	{ "l4ls-clkctrl@38_50", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_TIMER4_CLKCTRL, 0, nitems(l4ls_clkctrl_38_50), l4ls_clkctrl_38_50 },
+	{ "l4ls-clkctrl@38_54", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4ls-clkctrl@38_58", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_RNG_CLKCTRL, 0, nitems(l4ls_clkctrl_38_58), l4ls_clkctrl_38_58 },
+/* <0xac 0xc> */
+	{ "l4ls-clkctrl@38_74", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_GPIO2_CLKCTRL, 0, nitems(l4ls_clkctrl_38_74), l4ls_clkctrl_38_74 },
+	{ "l4ls-clkctrl@38_75", TI_CLKCTRL_GATE, 18, 0x40000, 0, AM3_L4LS_GPIO2_CLKCTRL, 1, nitems(l4ls_clkctrl_38_75), l4ls_clkctrl_38_75 },
+	{ "l4ls-clkctrl@38_78", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_GPIO3_CLKCTRL, 0, nitems(l4ls_clkctrl_38_78), l4ls_clkctrl_38_78 },
+	{ "l4ls-clkctrl@38_79", TI_CLKCTRL_GATE, 18, 0x40000, 0, AM3_L4LS_GPIO3_CLKCTRL, 1, nitems(l4ls_clkctrl_38_79), l4ls_clkctrl_38_79 },
+	{ "l4ls-clkctrl@38_7c", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_GPIO4_CLKCTRL, 0, nitems(l4ls_clkctrl_38_7c), l4ls_clkctrl_38_7c },
+	{ "l4ls-clkctrl@38_7d", TI_CLKCTRL_GATE, 18, 0x40000, 0, AM3_L4LS_GPIO4_CLKCTRL, 1, nitems(l4ls_clkctrl_38_7d), l4ls_clkctrl_38_7d },
+/* <0xc0 0x1c> */
+	{ "l4ls-clkctrl@38_88", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_D_CAN0_CLKCTRL, 0, nitems(l4ls_clkctrl_38_88), l4ls_clkctrl_38_88 },
+	{ "l4ls-clkctrl@38_8c", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_D_CAN1_CLKCTRL, 0, nitems(l4ls_clkctrl_38_8c), l4ls_clkctrl_38_8c },
+	{ "l4ls-clkctrl@38_90", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4ls-clkctrl@38_94", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_EPWMSS1_CLKCTRL, 0, nitems(l4ls_clkctrl_38_94), l4ls_clkctrl_38_94 },
+	{ "l4ls-clkctrl@38_98", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4ls-clkctrl@38_9c", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_EPWMSS0_CLKCTRL, 0, nitems(l4ls_clkctrl_38_9c), l4ls_clkctrl_38_9c },
+	{ "l4ls-clkctrl@38_a0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_EPWMSS2_CLKCTRL, 0, nitems(l4ls_clkctrl_38_a0), l4ls_clkctrl_38_a0 },
+/* <0xec 0xc> */
+	{ "l4ls-clkctrl@38_b4", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_TIMER5_CLKCTRL, 0, nitems(l4ls_clkctrl_38_b4), l4ls_clkctrl_38_b4 },
+	{ "l4ls-clkctrl@38_b8", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_TIMER6_CLKCTRL, 0, nitems(l4ls_clkctrl_38_b8), l4ls_clkctrl_38_b8 },
+	{ "l4ls-clkctrl@38_bc", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_MMC2_CLKCTRL, 0, nitems(l4ls_clkctrl_38_bc), l4ls_clkctrl_38_bc },
+/* <0xd4 0x8> */
+	{ "l4ls-clkctrl@38_d4", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_SPINLOCK_CLKCTRL, 0, nitems(l4ls_clkctrl_38_d4), l4ls_clkctrl_38_d4 },
+	{ "l4ls-clkctrl@38_d8", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_MAILBOX_CLKCTRL, 0, nitems(l4ls_clkctrl_38_d8), l4ls_clkctrl_38_d8 },
+/* <0x130 0x4> */
+	{ "l4ls-clkctrl@38_f8", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4LS_OCPWP_CLKCTRL, 0, nitems(l4ls_clkctrl_38_f8), l4ls_clkctrl_38_f8 },
+};
+
+static struct ti_clkctrl_lookup_table am33xx_l3s_clkctrl_table[] = {
+/* reg = <0x1c 0x4>, <0x30 0x8>, <0x68 0x4>, <0xf8 0x4> */
+/* <0x1c 0x4> */
+	{ "l3s-clkctrl@1c_0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L3S_USB_OTG_HS_CLKCTRL, 0, nitems(l3s_clkctrl_1c_0), l3s_clkctrl_1c_0 },
+/* <0x30 0x8> */
+	{ "l3s-clkctrl@1c_14", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L3S_GPMC_CLKCTRL, 0, nitems(l3s_clkctrl_1c_14), l3s_clkctrl_1c_14 },
+	{ "l3s-clkctrl@1c_18", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L3S_MCASP0_CLKCTRL, 0, nitems(l3s_clkctrl_1c_18), l3s_clkctrl_1c_18 },
+/* <0x68 0x4> */
+	{ "l3s-clkctrl@1c_4c", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L3S_MCASP1_CLKCTRL, 0, nitems(l3s_clkctrl_1c_4c), l3s_clkctrl_1c_4c },
+/* <0xf8 0x4> */
+	{ "l3s-clkctrl@1c_dc", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L3S_MMC3_CLKCTRL, 0, nitems(l3s_clkctrl_1c_dc), l3s_clkctrl_1c_dc },
+};
+
+static struct ti_clkctrl_lookup_table am33xx_l3_clkctrl_table[] = {
+/* reg = <0x24 0xc>, <0x94 0x10>, <0xbc 0x4>, <0xdc 0x8>, <0xfc 0x8>; */
+/* <0x24 0xc> */
+	{ "l3-clkctrl@24_0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L3_TPTC0_CLKCTRL, 0, nitems(l3_clkctrl_24_0), l3_clkctrl_24_0 },
+	{ "l3-clkctrl@24_4", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L3_EMIF_CLKCTRL, 0, nitems(l3_clkctrl_24_4), l3_clkctrl_24_4 },
+	{ "l3-clkctrl@24_8", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L3_OCMCRAM_CLKCTRL, 0, nitems(l3_clkctrl_24_8), l3_clkctrl_24_8 },
+/* <0x94 0x10> */
+	{ "l3-clkctrl@24_70", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L3_AES_CLKCTRL, 0, nitems(l3_clkctrl_24_70), l3_clkctrl_24_70 },
+	{ "l3-clkctrl@24_74", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l3-clkctrl@24_78", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l3-clkctrl@24_7c", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L3_SHAM_CLKCTRL, 0, nitems(l3_clkctrl_24_7c), l3_clkctrl_24_7c },
+/* <0xbc 0x4> */
+	{ "l3-clkctrl@24_98", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L3_TPCC_CLKCTRL, 0, nitems(l3_clkctrl_24_98), l3_clkctrl_24_98 },
+/* <0xdc 0x8> */
+	{ "l3-clkctrl@24_b8", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L3_L3_INSTR_CLKCTRL, 0, nitems(l3_clkctrl_24_b8), l3_clkctrl_24_b8 },
+	{ "l3-clkctrl@24_bc", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L3_L3_MAIN_CLKCTRL, 0, nitems(l3_clkctrl_24_bc), l3_clkctrl_24_bc },
+/* <0xfc 0x8> */
+	{ "l3-clkctrl@24_d8", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L3_TPTC1_CLKCTRL, 0, nitems(l3_clkctrl_24_d8), l3_clkctrl_24_d8 },
+	{ "l3-clkctrl@24_dc", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L3_TPTC2_CLKCTRL, 0, nitems(l3_clkctrl_24_dc), l3_clkctrl_24_dc },
+};
+
+static struct ti_clkctrl_lookup_table am33xx_l4hs_clkctrl_table[] = {
+/* reg = <0x120 0x4>; */
+	{ "l4hs-clkctrl@120_0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4HS_L4_HS_CLKCTRL, 0, nitems(l4hs_clkctrl_120_0), l4hs_clkctrl_120_0 },
+};
+
+static struct ti_clkctrl_lookup_table am33xx_pruss_clkctrl_table[] = {
+/* reg = <0xe8 0x4>; */
+	{ "pruss-ocp-clkctrl@e8_0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_PRUSS_OCP_PRUSS_CLKCTRL, 0, nitems(pruss_ocp_clkctrl_e8_0), pruss_ocp_clkctrl_e8_0 },
+};
+
+static struct ti_clkctrl_lookup_table am33xx_cpsw_clkctrl_table[] = {
+/* reg = <0x0 0x18>; */
+	{ "cpsw-125mhz-clkctrl@0_0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "cpsw-125mhz-clkctrl@0_4", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "cpsw-125mhz-clkctrl@0_8", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "cpsw-125mhz-clkctrl@0_c", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "cpsw-125mhz-clkctrl@0_10", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "cpsw-125mhz-clkctrl@0_14", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_CPSW_125MHZ_CPGMAC0_CLKCTRL, 0, nitems(cpsw_125mhz_clkctrl_0_14), cpsw_125mhz_clkctrl_0_14 },
+};
+
+static struct ti_clkctrl_lookup_table am33xx_lcdc_clkctrl_table[] = {
+/* reg = <0x18 0x4>; */
+	{ "lcdc-clkctrl@18_0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_LCDC_LCDC_CLKCTRL, 0, nitems(lcdc_clkctrl_18_0), lcdc_clkctrl_18_0 },
+};
+
+static struct ti_clkctrl_lookup_table am33xx_clk_24mhz_clkctrl_table[] = {
+/* reg = <0x14c 0x4>; */
+	{ "clk-24mhz-clkctrl@14c_0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL, 0, nitems(clk_24mhz_clkctrl_14c_0), clk_24mhz_clkctrl_14c_0 },
+};
+
+static struct ti_clkctrl_lookup_table am33xx_l4_wkup_clkctrl_table[] = {
+/* reg = <0x0 0x10>, <0xb4 0x24>; */
+/* <0x0 0x10> */
+	{ "l4-wkup-clkctrl@0_0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4-wkup-clkctrl@0_4", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4_WKUP_CONTROL_CLKCTRL, 0, nitems(l4_wkup_clkctrl_0_4), l4_wkup_clkctrl_0_4 },
+	{ "l4-wkup-clkctrl@0_8", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4_WKUP_GPIO1_CLKCTRL, 0, nitems(l4_wkup_clkctrl_0_8), l4_wkup_clkctrl_0_8 },
+	{ "l4-wkup-clkctrl@0_9", TI_CLKCTRL_GATE, 18, 0x40000, 0, AM3_L4_WKUP_GPIO1_CLKCTRL, 1, nitems(l4_wkup_clkctrl_0_9), l4_wkup_clkctrl_0_9 },
+	{ "l4-wkup-clkctrl@0_c", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4_WKUP_L4_WKUP_CLKCTRL, 0, nitems(l4_wkup_clkctrl_0_c), l4_wkup_clkctrl_0_c },
+/* <0xb4 0x24> */
+	{ "l4-wkup-clkctrl@0_b4", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4_WKUP_UART1_CLKCTRL, 0, nitems(l4_wkup_clkctrl_0_b4), l4_wkup_clkctrl_0_b4 },
+	{ "l4-wkup-clkctrl@0_b8", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4_WKUP_I2C1_CLKCTRL, 0, nitems(l4_wkup_clkctrl_0_b8), l4_wkup_clkctrl_0_b8 },
+	{ "l4-wkup-clkctrl@0_bc", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4_WKUP_ADC_TSC_CLKCTRL, 0, nitems(l4_wkup_clkctrl_0_bc), l4_wkup_clkctrl_0_bc },
+	{ "l4-wkup-clkctrl@0_c0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4_WKUP_SMARTREFLEX0_CLKCTRL, 0, nitems(l4_wkup_clkctrl_0_c0), l4_wkup_clkctrl_0_c0 },
+	{ "l4-wkup-clkctrl@0_c4", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4_WKUP_TIMER1_CLKCTRL, 0, nitems(l4_wkup_clkctrl_0_c4), l4_wkup_clkctrl_0_c4 },
+	{ "l4-wkup-clkctrl@0_c8", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4_WKUP_SMARTREFLEX1_CLKCTRL, 0, nitems(l4_wkup_clkctrl_0_c8), l4_wkup_clkctrl_0_c8 },
+	{ "l4-wkup-clkctrl@0_cc", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4-wkup-clkctrl@0_d0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4-wkup-clkctrl@0_d4", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4_WKUP_WD_TIMER2_CLKCTRL, 0, nitems(l4_wkup_clkctrl_0_d4), l4_wkup_clkctrl_0_d4 },
+};
+
+static struct ti_clkctrl_lookup_table am33xx_l3_aon_clkctrl_table[] = {
+/* reg = <0x14 0x4>; */
+	{ "l3-aon-clkctrl@14_0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+};
+
+static struct ti_clkctrl_lookup_table am33xx_l4_wkup_aon_clkctrl_table[] = {
+/* reg = <0xb0 0x4>; */
+	{ "l4-wkup-aon-clkctrl@b0_0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+};
+
+static struct ti_clkctrl_lookup_table am33xx_mpu_clkctrl_table[] = {
+/* reg = <0x0 0x8>; */
+	{ "mpu-clkctrl@0_0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "mpu-clkctrl@0_4", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_MPU_MPU_CLKCTRL, 0, nitems(mpu_clkctrl_0_4), mpu_clkctrl_0_4 },
+};
+
+static struct ti_clkctrl_lookup_table am33xx_l4_rtc_clkctrl_table[] = {
+/* reg = <0x0 0x4>; */
+	{ "l4-rtc-clkctrl@0_0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_L4_RTC_RTC_CLKCTRL, 0, nitems(l4_rtc_clkctrl_0_0), l4_rtc_clkctrl_0_0 },
+};
+
+static struct ti_clkctrl_lookup_table am33xx_gfx_l3_clkctrl_table[] = {
+/* reg = <0x0 0x8>; */
+	{ "gfx-l3-clkctrl@0_0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "gfx-l3-clkctrl@0_4", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, AM3_GFX_L3_GFX_CLKCTRL, 0, nitems(gfx_l3_clkctrl_0_4), gfx_l3_clkctrl_0_4 },
+};
+
+static struct ti_clkctrl_lookup_table am33xx_l4_cefuse_clkctrl_table[] = {
+/* reg = <0x0 0x24>; */
+	{ "l4-cefuse-clkctrl@0_0", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4-cefuse-clkctrl@0_4", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4-cefuse-clkctrl@0_8", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4-cefuse-clkctrl@0_c", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4-cefuse-clkctrl@0_10", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4-cefuse-clkctrl@0_14", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4-cefuse-clkctrl@0_18", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4-cefuse-clkctrl@0_1c", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+	{ "l4-cefuse-clkctrl@0_20", TI_CLKCTRL_NO_SUB_CLOCK, 0, 0, 0, 0, 0, 0, NULL },
+};
+
+/* === ti_div_clock.c === */
+PLIST(dpll_core_m4_ck_parent) = { "dpll_core_x2_ck" };
+PLIST(dpll_core_m5_ck_parent) = { "dpll_core_x2_ck" };
+PLIST(dpll_core_m6_ck_parent) = { "dpll_core_x2_ck" };
+PLIST(dpll_mpu_m2_ck_parent) = { "dpll_mpu_ck" };
+PLIST(dpll_ddr_m2_ck_parent) = { "dpll_ddr_ck" };
+PLIST(dpll_disp_m2_ck_parent) = { "dpll_disp_ck" };
+PLIST(dpll_per_m2_ck_parent) = { "dpll_per_ck" };
+PLIST(gfx_fck_div_ck_parent) = { "gfx_fclk_clksel_ck" };
+PLIST(clkout2_div_ck_parent) = { "sysclkout_pre_ck" };
+
+static struct parent_lookup_table div_parent_table[] = {
+{
+	"dpll_core_m4_ck",
+	nitems(dpll_core_m4_ck_parent),
+	dpll_core_m4_ck_parent
+},
+{
+	"dpll_core_m5_ck",
+	nitems(dpll_core_m5_ck_parent),
+	dpll_core_m5_ck_parent
+},
+{
+	"dpll_core_m6_ck",
+	nitems(dpll_core_m6_ck_parent),
+	dpll_core_m6_ck_parent
+},
+{
+	"dpll_mpu_m2_ck",
+	nitems(dpll_mpu_m2_ck_parent),
+	dpll_mpu_m2_ck_parent
+},
+{
+	"dpll_ddr_m2_ck",
+	nitems(dpll_ddr_m2_ck_parent),
+	dpll_ddr_m2_ck_parent
+},
+{
+	"dpll_disp_m2_ck",
+	nitems(dpll_disp_m2_ck_parent),
+	dpll_disp_m2_ck_parent
+},
+{
+	"dpll_per_m2_ck",
+	nitems(dpll_per_m2_ck_parent),
+	dpll_per_m2_ck_parent
+},
+{
+	"gfx_fck_div_ck",
+	nitems(gfx_fck_div_ck_parent),
+	gfx_fck_div_ck_parent
+},
+{
+	"clkout2_div_ck",
+	nitems(clkout2_div_ck_parent),
+	clkout2_div_ck_parent
+},
+};
+
+/* === ti_dpll_clock.c === */
+PLIST(dpll_core_ck_parent) = { "sys_clkin_ck", "sys_clkin_ck" };
+PLIST(dpll_core_x2_parent) = { "dpll_core_ck" };
+ 
+PLIST(dpll_mpu_ck_parent) = { "sys_clkin_ck", "sys_clkin_ck" };
+
+PLIST(dpll_ddr_ck_parent) = { "sys_clkin_ck", "sys_clkin_ck" };
+PLIST(dpll_ddr_m2_div2_ck_parent) = { "dpll_ddr_m2_ck" };
+
+PLIST(dpll_disp_ck_parent) = { "sys_clkin_ck", "sys_clkin_ck" };
+
+PLIST(dpll_per_ck_parent) = { "sys_clkin_ck", "sys_clkin_ck" };
+
+PLIST(dpll_per_m2_div4_wkupdm_ck_parent) = { "dpll_per_m2_ck" };
+PLIST(dpll_per_m2_div4_ck_parent) = { "dpll_per_m2_ck" };
+
+static struct parent_lookup_table dpll_parent_table[] = {
+{
+	"dpll_core_ck",
+	nitems(dpll_core_ck_parent),
+	dpll_core_ck_parent
+},
+{
+	"dpll_core_x2_ck",
+	nitems(dpll_core_x2_parent),
+	dpll_core_x2_parent
+},
+
+{
+	"dpll_mpu_ck",
+	nitems(dpll_mpu_ck_parent),
+	dpll_mpu_ck_parent
+},
+
+{
+	"dpll_ddr_ck",
+	nitems(dpll_ddr_ck_parent),
+	dpll_ddr_ck_parent
+},
+{
+	"dpll_ddr_m2_div2_ck",
+	nitems(dpll_ddr_m2_div2_ck_parent),
+	dpll_ddr_m2_div2_ck_parent
+},
+{
+	"dpll_disp_ck",
+	nitems(dpll_disp_ck_parent),
+	dpll_disp_ck_parent
+},
+
+{
+	"dpll_per_ck",
+	nitems(dpll_per_ck_parent),
+	dpll_per_ck_parent
+},
+{
+	"dpll_per_m2_div4_wkupdm_ck",
+	nitems(dpll_per_m2_div4_wkupdm_ck_parent),
+	dpll_per_m2_div4_wkupdm_ck_parent
+},
+{
+	"dpll_per_m2_div4_ck",
+	nitems(dpll_per_m2_div4_ck_parent),
+	dpll_per_m2_div4_ck_parent
+},
+};
+
+/* === ti_gate_clock.c === */
+PLIST(ehrpwm0_tbclk_parent) = { "l4ls_gclk" };
+PLIST(ehrpwm1_tbclk_parent) = { "l4ls_gclk" };
+PLIST(ehrpwm2_tbclk_parent) = { "l4ls_gclk" };
+PLIST(mmu_fck_parent) = { "dpll_core_m4_ck" };
+PLIST(usbotg_fck_parent) = { "dpll_per_ck" };
+PLIST(ieee5000_fck_parent) = { "dpll_core_m4_div2_ck" };
+PLIST(clkout2_ck_parent) = { "clkout2_div_ck" };
+
+static struct parent_lookup_table gate_parent_table[] = {
+{
+	"ehrpwm0_tbclk",
+	nitems(ehrpwm0_tbclk_parent),
+	ehrpwm0_tbclk_parent
+},
+{
+	"ehrpwm1_tbclk",
+	nitems(ehrpwm1_tbclk_parent),
+	ehrpwm1_tbclk_parent
+},
+{
+	"ehrpwm2_tbclk",
+	nitems(ehrpwm2_tbclk_parent),
+	ehrpwm2_tbclk_parent
+},
+{
+	"mmu_fck",
+	nitems(mmu_fck_parent),
+	mmu_fck_parent
+},
+{
+	"usbotg_fck",
+	nitems(usbotg_fck_parent),
+	usbotg_fck_parent
+},
+{
+	"ieee5000_fck",
+	nitems(ieee5000_fck_parent),
+	ieee5000_fck_parent
+},
+{
+	"clkout2_ck",
+	nitems(clkout2_ck_parent),
+	clkout2_ck_parent
+},
+};
+
+/* === ti_mux_clock.c === */
+PLIST(sys_clkin_ck_parent) = {
+	"virt_19200000_ck",
+	"virt_24000000_ck",
+	"virt_25000000_ck",
+	"virt_26000000_ck"
+};
+PLIST(pruss_ocp_gclk_parent) = {
+	"l3_gclk",
+	"dpll_disp_m2_ck"
+};
+PLIST(timer1_fck_parent) = {
+	"sys_clkin_ck",
+	"clk-24mhz-clkctrl@14c_0",
+	"tclkin_ck",
+	"clk_rc32k_ck",
+	"clk_32768_ck"
+};
+PLIST(timer2_fck_parent) = {
+	"tclkin_ck",
+	"sys_clkin_ck",
+	"clk-24mhz-clkctrl@14c_0"
+};
+PLIST(timer3_fck_parent) = {
+	"tclkin_ck",
+	"sys_clkin_ck",
+	"clk-24mhz-clkctrl@14c_0"
+};
+PLIST(timer4_fck_parent) = {
+	"tclkin_ck",
+	"sys_clkin_ck",
+	"clk-24mhz-clkctrl@14c_0"
+};
+PLIST(timer5_fck_parent) = {
+	"tclkin_ck",
+	"sys_clkin_ck",
+	"clk-24mhz-clkctrl@14c_0"
+};
+PLIST(timer6_fck_parent) = {
+	"tclkin_ck",
+	"sys_clkin_ck",
+	"clk-24mhz-clkctrl@14c_0"
+};
+PLIST(timer7_fck_parent) = {
+	"tclkin_ck",
+	"sys_clkin_ck",
+	"clk-24mhz-clkctrl@14c_0"
+};
+PLIST(wdt1_fck_parent) = {
+	"clk_rc32k_ck",
+	"clk-24mhz-clkctrl@14c_0"
+};
+PLIST(cpsw_cpts_tft_clk_parent) = {
+	"dpll_core_m5_ck",
+	"dpll_core_m4_ck"
+};
+PLIST(gpio0_dbclk_mux_ck_parent) = {
+	"clk_rc32k_ck",
+	"clk_32768_ck",
+	"clk-24mhz-clkctrl@14c_0"
+};
+PLIST(lcd_gclk_parent) = {
+	"dpll_disp_m2_ck",
+	"dpll_core_m5_ck",
+	"dpll_per_m2_ck"
+};
+PLIST(gfx_fclk_clksel_ck_parent) = {
+	"dpll_core_m4_ck",
+	"dpll_per_m2_ck"
+};
+PLIST(sysclkout_pre_ck_parent) = {
+	"clk_32768_ck",
+	"l3_gclk",
+	"dpll_ddr_m2_ck",
+	"dpll_per_m2_ck",
+	"lcd_gclk"
+};
+
+static struct parent_lookup_table mux_parent_table[] =
+{
+{
+	"sys_clkin_ck",
+	nitems(sys_clkin_ck_parent),
+	sys_clkin_ck_parent
+},
+{
+	"pruss_ocp_gclk",
+	nitems(pruss_ocp_gclk_parent),
+	pruss_ocp_gclk_parent
+},
+{
+	"timer1_fck",
+	nitems(timer1_fck_parent),
+	timer1_fck_parent
+},
+{
+	"timer2_fck",
+	nitems(timer2_fck_parent),
+	timer2_fck_parent
+},
+{
+	"timer3_fck",
+	nitems(timer3_fck_parent),
+	timer3_fck_parent
+},
+{
+	"timer4_fck",
+	nitems(timer4_fck_parent),
+	timer4_fck_parent
+},
+{
+	"timer5_fck",
+	nitems(timer5_fck_parent),
+	timer5_fck_parent
+},
+{
+	"timer6_fck",
+	nitems(timer6_fck_parent),
+	timer6_fck_parent
+},
+{
+	"timer7_fck",
+	nitems(timer7_fck_parent),
+	timer7_fck_parent
+},
+{
+	"wdt1_fck",
+	nitems(wdt1_fck_parent),
+	wdt1_fck_parent
+},
+{
+	"cpsw_cpts_rft_clk",
+	nitems(cpsw_cpts_tft_clk_parent),
+	cpsw_cpts_tft_clk_parent
+},
+{
+	"gpio0_dbclk_mux_ck",
+	nitems(gpio0_dbclk_mux_ck_parent),
+	gpio0_dbclk_mux_ck_parent
+},
+{
+	"lcd_gclk",
+	nitems(lcd_gclk_parent),
+	lcd_gclk_parent
+},
+{
+	"gfx_fclk_clksel_ck",
+	nitems(gfx_fclk_clksel_ck_parent),
+	gfx_fclk_clksel_ck_parent
+},
+{
+	"sysclkout_pre_ck",
+	nitems(sysclkout_pre_ck_parent),
+	sysclkout_pre_ck_parent
+},
+};
+
+#endif /* __AM33XX_H__ */
diff --git a/sys/arm/ti/clk/ti_clk_clkctrl.h b/sys/arm/ti/clk/ti_clk_clkctrl.h
--- a/sys/arm/ti/clk/ti_clk_clkctrl.h
+++ b/sys/arm/ti/clk/ti_clk_clkctrl.h
@@ -32,8 +32,8 @@
 
 struct ti_clk_clkctrl_def {
 	struct clknode_init_def 	clkdef;
-	bool				gdbclk;
 	uint32_t			register_offset;
+	uint8_t				flags;
 };
 
 int ti_clknode_clkctrl_register(struct clkdom *clkdom, struct ti_clk_clkctrl_def *clkdef);
diff --git a/sys/arm/ti/clk/ti_clk_clkctrl.c b/sys/arm/ti/clk/ti_clk_clkctrl.c
--- a/sys/arm/ti/clk/ti_clk_clkctrl.c
+++ b/sys/arm/ti/clk/ti_clk_clkctrl.c
@@ -33,6 +33,7 @@
 #include <dev/clk/clk.h>
 
 #include <arm/ti/clk/ti_clk_clkctrl.h>
+#include <arm/ti/clk/ti_clock_common.h>
 
 #include "clkdev_if.h"
 
@@ -46,25 +47,23 @@
  * clknode for clkctrl, implements gate and mux (for gpioc)
  */
 
-#define GPIO_X_GDBCLK_MASK	0x00040000
 #define IDLEST_MASK		0x00030000
 #define MODULEMODE_MASK		0x00000003
 
-#define GPIOX_GDBCLK_ENABLE	0x00040000
-#define GPIOX_GDBCLK_DISABLE	0x00000000
 #define IDLEST_FUNC		0x00000000
 #define IDLEST_TRANS		0x00010000
 #define IDLEST_IDLE		0x00020000
 #define IDLEST_DISABLE		0x00030000
 
 #define MODULEMODE_DISABLE	0x0
-#define MODULEMODE_ENABLE	0x2
+#define MODULEMODE_ENABLE_HW	0x1
+#define MODULEMODE_ENABLE_SW	0x2
 
 struct ti_clkctrl_clknode_sc {
 	device_t	dev;
-	bool		gdbclk;
 	/* omap4-cm range.host + ti,clkctrl reg[0] */
 	uint32_t	register_offset;
+	uint8_t		flags;
 };
 
 #define	WRITE4(_clk, off, val)						\
@@ -88,90 +87,48 @@
 	return (0);
 }
 
-static int
-ti_clkctrl_set_gdbclk_gate(struct clknode *clk, bool enable)
-{
-	struct ti_clkctrl_clknode_sc *sc;
-	uint32_t val, gpio_x_gdbclk;
-	uint32_t timeout = 100;
-
-	sc = clknode_get_softc(clk);
-
-	READ4(clk, sc->register_offset, &val);
-	DPRINTF(sc->dev, "val(%x) & (%x | %x = %x)\n",
-	    val, GPIO_X_GDBCLK_MASK, MODULEMODE_MASK,
-	    GPIO_X_GDBCLK_MASK | MODULEMODE_MASK);
-
-	if (enable) {
-		val = val & MODULEMODE_MASK;
-		val |= GPIOX_GDBCLK_ENABLE;
-	} else {
-		val = val & MODULEMODE_MASK;
-		val |= GPIOX_GDBCLK_DISABLE;
-	}
-
-	DPRINTF(sc->dev, "val %x\n", val);
-	WRITE4(clk, sc->register_offset, val);
-
-	/* Wait */
-	while (timeout) {
-		READ4(clk, sc->register_offset, &val);
-		gpio_x_gdbclk = val & GPIO_X_GDBCLK_MASK;
-		if (enable && (gpio_x_gdbclk == GPIOX_GDBCLK_ENABLE))
-			break;
-		else if (!enable && (gpio_x_gdbclk == GPIOX_GDBCLK_DISABLE))
-			break;
-		DELAY(10);
-		timeout--;
-	}
-	if (timeout == 0) {
-		device_printf(sc->dev, "ti_clkctrl_set_gdbclk_gate: Timeout\n");
-		return (1);
-	}
-
-	return (0);
-}
-
 static int
 ti_clkctrl_set_gate(struct clknode *clk, bool enable)
 {
 	struct ti_clkctrl_clknode_sc *sc;
-	uint32_t	val, idlest, module;
+	uint32_t	val, idlest, modulemode_reg, modulemode_val=0;
 	uint32_t timeout=100;
-	int err;
 
 	sc = clknode_get_softc(clk);
 
-	if (sc->gdbclk) {
-		err = ti_clkctrl_set_gdbclk_gate(clk, enable);
-		return (err);
-	}
-
+	DEVICE_LOCK(clk);
 	READ4(clk, sc->register_offset, &val);
 
-	if (enable)
-		WRITE4(clk, sc->register_offset, MODULEMODE_ENABLE);
-	else
+	if (enable == false)
 		WRITE4(clk, sc->register_offset, MODULEMODE_DISABLE);
+	/* enable == true for following two */
+	else if ((sc->flags & TI_CLKCTRL_FLAGS_MM_HW) == TI_CLKCTRL_FLAGS_MM_HW) {
+		modulemode_val = MODULEMODE_ENABLE_HW;
+		WRITE4(clk, sc->register_offset, MODULEMODE_ENABLE_HW);
+	} else {
+		modulemode_val = MODULEMODE_ENABLE_SW;
+		WRITE4(clk, sc->register_offset, MODULEMODE_ENABLE_SW);
+	}
 
 	while (timeout) {
 		READ4(clk, sc->register_offset, &val);
 		idlest = val & IDLEST_MASK;
-		module = val & MODULEMODE_MASK;
-		if (enable &&
-		    (idlest == IDLEST_FUNC || idlest == IDLEST_TRANS) &&
-		    module == MODULEMODE_ENABLE)
+		modulemode_reg = val & MODULEMODE_MASK;
+		if (enable == true &&
+		    (idlest == IDLEST_FUNC || idlest == IDLEST_IDLE) &&
+		    modulemode_reg == modulemode_val)
 			break;
-		else if (!enable &&
+		else if (enable == false &&
 		    idlest == IDLEST_DISABLE &&
-		    module == MODULEMODE_DISABLE)
+		    modulemode_reg == MODULEMODE_DISABLE)
 			break;
 		DELAY(10);
 		timeout--;
 	}
 
+	DEVICE_UNLOCK(clk);
 	if (timeout == 0) {
-		device_printf(sc->dev, "ti_clkctrl_set_gate: Timeout\n");
+		DPRINTF(sc->dev, "ti_clkctrl_set_gate: Timeout\n");
 		return (1);
 	}
 
@@ -200,14 +157,16 @@
 	    &clkdef->clkdef);
 
 	if (clk == NULL) {
+		DPRINTF(sc->dev, "clknode_create failed.\n");
 		return (1);
 	}
 
 	sc = clknode_get_softc(clk);
 	sc->register_offset = clkdef->register_offset;
-	sc->gdbclk = clkdef->gdbclk;
+	sc->flags = clkdef->flags;
 
 	if (clknode_register(clkdom, clk) == NULL) {
+		DPRINTF(sc->dev, "clknode_register failed.\n");
 		return (2);
 	}
 	return (0);
diff --git a/sys/arm/ti/clk/ti_clk_dpll.h b/sys/arm/ti/clk/ti_clk_dpll.h
--- a/sys/arm/ti/clk/ti_clk_dpll.h
+++ b/sys/arm/ti/clk/ti_clk_dpll.h
@@ -87,6 +87,9 @@
 	struct ti_clk_factor	ti_clksel_div;
 
 	uint32_t		ti_autoidle_offset;
+
+	uint32_t		ti_ssc_deltam_offset;
+	uint32_t		ti_ssc_modfreq_offset;
 };
 
 int ti_clknode_dpll_register(struct clkdom *clkdom, struct ti_clk_dpll_def *clkdef);
diff --git a/sys/arm/ti/clk/ti_clk_dpll.c b/sys/arm/ti/clk/ti_clk_dpll.c
--- a/sys/arm/ti/clk/ti_clk_dpll.c
+++ b/sys/arm/ti/clk/ti_clk_dpll.c
@@ -57,6 +57,8 @@
 	struct ti_clk_factor	p; /* ti_clksel_div */
 
 	uint32_t		ti_autoidle_offset;
+	uint32_t		ti_ssc_deltam_offset;
+	uint32_t		ti_ssc_modfreq_offset;
 };
 
 #define	WRITE4(_clk, off, val)						\
@@ -324,6 +326,8 @@
 	sc->p.flags = clkdef->ti_clksel_div.flags;
 
 	sc->ti_autoidle_offset = clkdef->ti_autoidle_offset;
+	sc->ti_ssc_deltam_offset = clkdef->ti_ssc_deltam_offset;
+	sc->ti_ssc_modfreq_offset = clkdef->ti_ssc_modfreq_offset;
 
 	clknode_register(clkdom, clk);
 
diff --git a/sys/arm/ti/clk/ti_clkctrl.c b/sys/arm/ti/clk/ti_clkctrl.c
--- a/sys/arm/ti/clk/ti_clkctrl.c
+++ b/sys/arm/ti/clk/ti_clkctrl.c
@@ -41,14 +41,20 @@
 #include <vm/vm_kern.h>
 #include <vm/pmap.h>
 
+#include <dev/clk/clk_gate.h>
+#include <dev/clk/clk_div.h>
+#include <dev/clk/clk_mux.h>
 #include <dev/fdt/simplebus.h>
 
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
+#include <arm/ti/clk/am33xx.h>
+#include <arm/ti/clk/ti_clock_common.h>
 #include <arm/ti/clk/ti_clk_clkctrl.h>
 #include <arm/ti/ti_omap4_cm.h>
 #include <arm/ti/ti_cpuid.h>
+#include <dt-bindings/clock/am3.h>
 
 #if 0
 #define DPRINTF(dev, msg...) device_printf(dev, msg)
@@ -56,10 +62,6 @@
 #define DPRINTF(dev, msg...)
 #endif
 
-#define L4LS_CLKCTRL_38 	2
-#define L4_WKUP_CLKCTRL_0	1
-#define NO_SPECIAL_REG		0
-
 /* Documentation/devicetree/bindings/clock/ti-clkctrl.txt */
 
 #define TI_CLKCTRL_L4_WKUP	5
@@ -89,9 +91,9 @@
 static int ti_clkctrl_detach(device_t dev);
 int clkctrl_ofw_map(struct clkdom *clkdom, uint32_t ncells,
     phandle_t *cells, struct clknode **clk);
+
 static int
-create_clkctrl(struct ti_clkctrl_softc *sc, cell_t *reg, uint32_t index, uint32_t reg_offset,
-    uint64_t parent_offset, const char *org_name, bool special_gdbclk_reg);
+create_clkctrl(struct ti_clkctrl_softc *sc, struct ti_clkctrl_lookup_table *table, int nitems, uint32_t reg_offset);
 
 static int
 ti_clkctrl_probe(device_t dev)
@@ -103,6 +105,9 @@
 		return (ENXIO);
 
 	device_set_desc(dev, "TI clkctrl");
+	if (bootverbose == 0)
+		device_quiet(dev);
+
 
 	return (BUS_PROBE_DEFAULT);
 }
@@ -114,11 +119,9 @@
 	phandle_t node;
 	cell_t	*reg;
 	ssize_t numbytes_reg;
-	int num_reg, err, ti_clock_cells;
-	uint32_t index, reg_offset, reg_address;
+	int err, ti_clock_cells;
 	const char *org_name;
 	uint64_t parent_offset;
-	uint8_t special_reg = NO_SPECIAL_REG;
 
 	sc = device_get_softc(dev);
 	sc->dev = dev;
@@ -128,12 +131,12 @@
 	err = OF_searchencprop(node, "#clock-cells",
 		&ti_clock_cells, sizeof(ti_clock_cells));
 	if (err == -1) {
-		device_printf(sc->dev, "Failed to get #clock-cells\n");
+		DPRINTF(sc->dev, "Failed to get #clock-cells\n");
 		return (ENXIO);
 	}
 
 	if (ti_clock_cells != 2) {
-		device_printf(sc->dev, "clock cells(%d) != 2\n",
+		DPRINTF(sc->dev, "clock cells(%d) != 2\n",
 			ti_clock_cells);
 		return (ENXIO);
 	}
@@ -141,10 +144,9 @@
 	/* Grab the content of reg properties */
 	numbytes_reg = OF_getproplen(node, "reg");
 	if (numbytes_reg == 0) {
-		device_printf(sc->dev, "reg property empty - check your devicetree\n");
+		DPRINTF(sc->dev, "reg property empty - check your devicetree\n");
 		return (ENXIO);
 	}
-	num_reg = numbytes_reg / sizeof(cell_t);
 
 	reg = malloc(numbytes_reg, M_DEVBUF, M_WAITOK);
 	OF_getencprop(node, "reg", reg, numbytes_reg);
@@ -165,69 +167,82 @@
 	/* Get parent range */
 	parent_offset = ti_omap4_cm_get_simplebus_base_host(device_get_parent(dev));
 
-	/* Check if this is a clkctrl with special registers like gpio */
+	/* Find which clkctrl to populate */
 	switch (ti_chip()) {
 #ifdef SOC_OMAP4
 	case CHIP_OMAP_4:
 		/* FIXME: Todo */
 		break;
-
 #endif /* SOC_OMAP4 */
+
 #ifdef SOC_TI_AM335X
 	/* Checkout TRM 8.1.12.1.29 - 8.1.12.31 and 8.1.12.2.3
 	 * and the DTS.
 	 */
 	case CHIP_AM335X:
-		if (strcmp(org_name, "l4ls-clkctrl@38") == 0)
-			special_reg = L4LS_CLKCTRL_38;
-		else if (strcmp(org_name, "l4-wkup-clkctrl@0") == 0)
-			special_reg = L4_WKUP_CLKCTRL_0;
-		break;
+	if (strcmp(org_name, "l4ls_clkctrl") == 0)
+		err = create_clkctrl(sc, am33xx_l4ls_clkctrl_table,
+		    nitems(am33xx_l4ls_clkctrl_table), parent_offset + AM3_L4LS_CLKCTRL_OFFSET);
+	else if (strcmp(org_name, "l3s_clkctrl") == 0)
+		err = create_clkctrl(sc, am33xx_l3s_clkctrl_table,
+		    nitems(am33xx_l3s_clkctrl_table), parent_offset + AM3_L3S_CLKCTRL_OFFSET);
+	else if (strcmp(org_name, "l3_clkctrl") == 0)
+		err = create_clkctrl(sc, am33xx_l3_clkctrl_table,
+		    nitems(am33xx_l3_clkctrl_table), parent_offset + AM3_L3_CLKCTRL_OFFSET);
+	else if (strcmp(org_name, "l4hs_clkctrl") == 0)
+		err = create_clkctrl(sc, am33xx_l4hs_clkctrl_table,
+		    nitems(am33xx_l4hs_clkctrl_table), parent_offset + AM3_L4HS_CLKCTRL_OFFSET);
+	else if (strcmp(org_name, "pruss_ocp_clkctrl") == 0)
+		err = create_clkctrl(sc, am33xx_pruss_clkctrl_table,
+		    nitems(am33xx_pruss_clkctrl_table), parent_offset + AM3_PRUSS_OCP_CLKCTRL_OFFSET);
+	else if (strcmp(org_name, "cpsw_125mhz_clkctrl") == 0)
+		err = create_clkctrl(sc, am33xx_cpsw_clkctrl_table,
+		    nitems(am33xx_cpsw_clkctrl_table), parent_offset + 0);
+	else if (strcmp(org_name, "lcdc_clkctrl") == 0)
+		err = create_clkctrl(sc, am33xx_lcdc_clkctrl_table,
+		    nitems(am33xx_lcdc_clkctrl_table), parent_offset + AM3_LCDC_CLKCTRL_OFFSET);
+	else if (strcmp(org_name, "clk_24mhz_clkctrl") == 0)
+		err = create_clkctrl(sc, am33xx_clk_24mhz_clkctrl_table,
+		    nitems(am33xx_clk_24mhz_clkctrl_table), parent_offset + AM3_CLK_24MHZ_CLKCTRL_OFFSET);
+	else if (strcmp(org_name, "l4_wkup_clkctrl") == 0)
+		err = create_clkctrl(sc, am33xx_l4_wkup_clkctrl_table,
+		    nitems(am33xx_l4_wkup_clkctrl_table), parent_offset + 0);
+	else if (strcmp(org_name, "l3_aon_clkctrl") == 0)
+		err = create_clkctrl(sc, am33xx_l3_aon_clkctrl_table,
+		    nitems(am33xx_l3_aon_clkctrl_table), parent_offset + AM3_L3_AON_CLKCTRL_OFFSET);
+	else if (strcmp(org_name, "l4_wkup_aon_clkctrl") == 0)
+		err = create_clkctrl(sc, am33xx_l4_wkup_aon_clkctrl_table,
+		    nitems(am33xx_l4_wkup_aon_clkctrl_table), parent_offset + AM3_L4_WKUP_AON_CLKCTRL_OFFSET);
+	else if (strcmp(org_name, "mpu_clkctrl") == 0)
+		err = create_clkctrl(sc, am33xx_mpu_clkctrl_table,
+		    nitems(am33xx_mpu_clkctrl_table), parent_offset + 0);
+	else if (strcmp(org_name, "l4_rtc_clkctrl") == 0)
+		err = create_clkctrl(sc, am33xx_l4_rtc_clkctrl_table,
+		    nitems(am33xx_l4_rtc_clkctrl_table), parent_offset + 0);
+	else if (strcmp(org_name, "gfx_l3_clkctrl") == 0)
+		err = create_clkctrl(sc, am33xx_gfx_l3_clkctrl_table,
+		    nitems(am33xx_gfx_l3_clkctrl_table), parent_offset + 0);
+	else if (strcmp(org_name, "l4_cefuse_clkctrl") == 0)
+		err = create_clkctrl(sc, am33xx_l4_cefuse_clkctrl_table,
+		    nitems(am33xx_l4_cefuse_clkctrl_table), parent_offset + 0);
+	else
+		panic("Not expected clkctrl %s", org_name);
+	break;
 #endif /* SOC_TI_AM335X */
 	default:
 		break;
 	}
 
-	/* reg property has a pair of (base address, length) */
-	for (index = 0; index < num_reg; index += 2) {
-		for (reg_offset = 0; reg_offset < reg[index+1]; reg_offset += sizeof(cell_t)) {
-			err = create_clkctrl(sc, reg, index, reg_offset, parent_offset,
-			    org_name, false);
-			if (err)
-				goto cleanup;
-
-			/* Create special clkctrl for GDBCLK in GPIO registers */
-			switch (special_reg) {
-			case NO_SPECIAL_REG:
-				break;
-			case L4LS_CLKCTRL_38:
-				reg_address = reg[index] + reg_offset-reg[0];
-				if (reg_address == 0x74 ||
-				    reg_address == 0x78 ||
-				    reg_address == 0x7C)
-				{
-					err = create_clkctrl(sc, reg, index, reg_offset,
-					    parent_offset, org_name, true);
-					if (err)
-						goto cleanup;
-				}
-				break;
-			case L4_WKUP_CLKCTRL_0:
-				reg_address = reg[index] + reg_offset - reg[0];
-				if (reg_address == 0x8)
-				{
-					err = create_clkctrl(sc, reg, index, reg_offset,
-					    parent_offset, org_name, true);
-					if (err)
-						goto cleanup;
-				}
-				break;
-			} /* switch (special_reg) */
-		} /* inner for */
-	} /* for */
+	if (err != 0) {
+		DPRINTF(sc->dev, "%s failed to create clock\n",
+			org_name);
+		err = ENXIO;
+		goto cleanup;
+	}
+
 
 	err = clkdom_finit(sc->clkdom);
-	if (err) {
+	if (err != 0) {
 		DPRINTF(sc->dev, "Clk domain finit fails %x.\n", err);
 		err = ENXIO;
 		goto cleanup;
@@ -238,7 +253,7 @@
 
 	free(reg, M_DEVBUF);
 
-	if (err)
+	if (err != 0)
 		return (err);
 
 	return (bus_generic_attach(dev));
@@ -277,53 +292,98 @@
 }
 
 static int
-create_clkctrl(struct ti_clkctrl_softc *sc, cell_t *reg, uint32_t index, uint32_t reg_offset,
-    uint64_t parent_offset, const char *org_name, bool special_gdbclk_reg) {
-	struct ti_clk_clkctrl_def def;
-	char *name;
-	size_t name_len;
+create_clkctrl(struct ti_clkctrl_softc *sc, struct ti_clkctrl_lookup_table *table, int nitems, uint32_t reg_offset) {
+	struct ti_clk_clkctrl_def 	clkctrl;
+	struct clk_gate_def		gate;
+	struct clk_mux_def		mux;
+	struct clk_div_def		divider;
 	int err;
 
-	name_len = strlen(org_name) + 1 + 5; /* 5 = _xxxx */
-	name = malloc(name_len, M_OFWPROP, M_WAITOK);
+	for (int index = 0; index < nitems; index++) {
+	switch (table[index].clk_type) {
+	case TI_CLKCTRL_NO_SUB_CLOCK:
+		DPRINTF(sc->dev, "NO_SUB_CLOCK: %s\n", table[index].node_name);
+		/* set flags and name */
+		clkctrl.clkdef.flags = CLK_NODE_STATIC_STRINGS;
+		clkctrl.clkdef.name = table[index].node_name;
+		clkctrl.clkdef.id = table[index].offset + table[index].id_subclock;
 
-	/*
-	 * Check out XX_CLKCTRL-INDEX(offset)-macro dance in
-	 * sys/gnu/dts/dts/include/dt-bindings/clock/am3.h
-	 * sys/gnu/dts/dts/include/dt-bindings/clock/am4.h
-	 * sys/gnu/dts/dts/include/dt-bindings/clock/dra7.h
-	 * reg[0] are in practice the same as the offset described in the dts.
-	 */
-	/* special_gdbclk_reg are 0 or 1 */
-	def.clkdef.id = reg[index] + reg_offset - reg[0] + special_gdbclk_reg;
-	def.register_offset = parent_offset + reg[index] + reg_offset;
+		/* Handle parents */
+		clkctrl.clkdef.parent_cnt = table[index].parent_cnt;
+		clkctrl.clkdef.parent_names = table[index].parents;
 
-	/* Indicate this clkctrl is special and dont use IDLEST/MODULEMODE */
-	def.gdbclk = special_gdbclk_reg;
+		clkctrl.register_offset = table[index].offset + reg_offset;
+		clkctrl.flags = table[index].flags;
 
-	/* Make up an uniq name in the namespace for each clkctrl */
-	snprintf(name, name_len, "%s_%x",
-		org_name, def.clkdef.id);
-	def.clkdef.name = (const char *) name;
-
-	DPRINTF(sc->dev, "ti_clkctrl_attach: reg[%d]: %s %x\n",
-		index, def.clkdef.name, def.clkdef.id);
-
-	/* No parent name */
-	def.clkdef.parent_cnt = 0;
-
-	/* set flags */
-	def.clkdef.flags = 0x0;
+		/* Register the clkctrl */
+		err = ti_clknode_clkctrl_register(sc->clkdom, &clkctrl);
+		break;
+	case TI_CLKCTRL_GATE:
+		DPRINTF(sc->dev, "GATE %s\n", table[index].node_name);
+		/* set flags and name */
+		gate.clkdef.flags = CLK_NODE_STATIC_STRINGS;
+		gate.clkdef.name = table[index].node_name;
+		gate.clkdef.id = table[index].offset + table[index].id_subclock;
+		gate.clkdef.parent_names = table[index].parents;
+		gate.clkdef.parent_cnt = table[index].parent_cnt;
+
+		gate.offset = table[index].offset + reg_offset;
+		gate.shift = table[index].shift;
+		gate.mask = table[index].mask;
+		gate.on_value = 1;
+		gate.off_value = 0;
+		gate.gate_flags = 0;
+
+		err = clknode_gate_register(sc->clkdom, &gate);
+		break;
+	case TI_CLKCTRL_MUX:
+		DPRINTF(sc->dev, "MUX %s\n", table[index].node_name);
+		/* set flags and name */
+		mux.clkdef.flags = CLK_NODE_STATIC_STRINGS;
+		mux.clkdef.name = table[index].node_name;
+		mux.clkdef.id = table[index].offset + table[index].id_subclock;
+		mux.clkdef.parent_names = table[index].parents;
+		mux.clkdef.parent_cnt = table[index].parent_cnt;
+
+		mux.offset = table[index].offset + reg_offset;
+		mux.shift = table[index].shift;
+		mux.width = fls(table[index].mask >> table[index].shift);
+
+		err = clknode_mux_register(sc->clkdom, &mux);
+		break;
+	case TI_CLKCTRL_DIVIDER:
+		DPRINTF(sc->dev, "DIVIDER %s\n", table[index].node_name);
+		/* set flags and name */
+		divider.clkdef.flags = CLK_NODE_STATIC_STRINGS;
+		divider.clkdef.name = table[index].node_name;
+		divider.clkdef.id = table[index].offset + table[index].id_subclock;
+		divider.clkdef.parent_names = table[index].parents;
+		divider.clkdef.parent_cnt = table[index].parent_cnt;
+
+		divider.offset = table[index].offset + reg_offset;
+		divider.i_shift = table[index].shift;
+		divider.i_width = fls(table[index].mask >> table[index].shift);
+		divider.f_shift = 0;
+		divider.f_width = 0;
+		divider.div_flags = 0;
+		divider.div_table = NULL;
+
+		err = clknode_div_register(sc->clkdom, &divider);
+		break;
+	default:
+		panic("clk_type %x not implemented\n",
+			table[index].clk_type);
+		break;
+	}
 
-	/* Register the clkctrl */
-	err = ti_clknode_clkctrl_register(sc->clkdom, &def);
-	if (err) {
+	if (err != 0) {
 		DPRINTF(sc->dev,
 			"ti_clknode_clkctrl_register[%d:%d] failed %x\n",
 			index, reg_offset, err);
 		err = ENXIO;
+		break;
 	}
-	OF_prop_free(name);
+	} /* for */
 	return (err);
 }
 
diff --git a/sys/arm/ti/clk/ti_clock_common.h b/sys/arm/ti/clk/ti_clock_common.h
new file mode 100644
--- /dev/null
+++ b/sys/arm/ti/clk/ti_clock_common.h
@@ -0,0 +1,74 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Oskar Holmlund <oskar.holmlund@ohdata.se>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __TI_CLOCK_COMMON_H__
+#define __TI_CLOCK_COMMON_H__
+
+#include <sys/cdefs.h>
+struct parent_lookup_table {
+        const char      *node_name;
+	int		parent_cnt;
+	const char	**parent_names;
+};
+
+/* sub clock types */
+#define TI_CLKCTRL_GATE		0x3
+#define TI_CLKCTRL_MUX          0x2
+#define TI_CLKCTRL_DIVIDER      0x1
+#define TI_CLKCTRL_NO_SUB_CLOCK	0x0
+
+/* flags */
+#define TI_CLKCTRL_FLAGS_MM_HW  0x1
+#define TI_CLKCTRL_FLAGS_MM_SW  0x2
+
+struct ti_clkctrl_lookup_table {
+        const char      *node_name;
+        uint8_t         clk_type;
+        /* clk_gate/mux/div_def */
+        uint32_t        shift;
+        uint32_t        mask;
+	uint8_t		flags;
+        uint32_t        offset;
+        /* clknode_init_def */
+	int		id_subclock; /* id = offset + id_subclock */
+        int             parent_cnt;
+        const char      **parents;
+};
+
+
+/* From rk3399_cru.c & rk_cru.c */
+#define PLIST(x) static const char *x[]
+
+#define LINK(_name)						\
+{								\
+	.clkdef.id = 0,						\
+	.clkdef.name = _name,					\
+	.clkdef.parent_names = NULL,				\
+	.clkdef.parent_cnt = 0,					\
+	.clkdef.flags = CLK_NODE_STATIC_STRINGS,		\
+}
+#endif /* __TI_CLOCK_COMMON_H__ */
diff --git a/sys/arm/ti/clk/ti_divider_clock.c b/sys/arm/ti/clk/ti_divider_clock.c
--- a/sys/arm/ti/clk/ti_divider_clock.c
+++ b/sys/arm/ti/clk/ti_divider_clock.c
@@ -25,6 +25,11 @@
  * SUCH DAMAGE.
  */
 
+/*
+ * Devicetree description
+ * Documentation/devicetree/bindings/clock/ti/divider.txt
+ */
+
 #include <sys/param.h>
 #include <sys/conf.h>
 #include <sys/bus.h>
@@ -37,10 +42,15 @@
 #include <dev/fdt/simplebus.h>
 
 #include <dev/clk/clk_div.h>
+#include <dev/syscon/syscon.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
-#include "clock_common.h"
+#include <arm/ti/clk/am33xx.h>
+#include <arm/ti/clk/ti_clock_common.h>
+#include <arm/ti/clk/ti_clksel.h>
+#include "clkdev_if.h"
+#include "syscon_if.h"
 
 #if 0
 #define DPRINTF(dev, msg...) device_printf(dev, msg)
@@ -48,18 +58,12 @@
 #define DPRINTF(dev, msg...)
 #endif
 
-/*
- * Devicetree description
- * Documentation/devicetree/bindings/clock/ti/divider.txt
- */
-
 struct ti_divider_softc {
-	device_t		sc_dev;
-	bool			attach_done;
+	device_t		dev;
 	struct clk_div_def	div_def;
 
-	struct clock_cell_info	clock_cell;
 	struct clkdom		*clkdom;
+	struct syscon		*syscon;
 };
 
 static int ti_divider_probe(device_t dev);
@@ -77,30 +81,64 @@
 };
 
 static int
-register_clk(struct ti_divider_softc *sc) {
-	int err;
+ti_divider_clkdev_write_4(device_t dev, bus_addr_t addr, uint32_t val)
+{
+	struct ti_divider_softc *sc;
 
-	sc->clkdom = clkdom_create(sc->sc_dev);
-	if (sc->clkdom == NULL) {
-		DPRINTF(sc->sc_dev, "Failed to create clkdom\n");
-		return (ENXIO);
-	}
+	sc = device_get_softc(dev);
+	DPRINTF(sc->dev, "ti_divider_clkdev_write_4: addr %x val %x\n",
+	    addr, val);
+	return (SYSCON_UNLOCKED_WRITE_4(sc->syscon, addr, val));
+}
 
-	err = clknode_div_register(sc->clkdom, &sc->div_def);
-	if (err) {
-		DPRINTF(sc->sc_dev, "clknode_div_register failed %x\n", err);
-		return (ENXIO);
-	}
+static int
+ti_divider_clkdev_read_4(device_t dev, bus_addr_t addr, uint32_t *val)
+{
+	struct ti_divider_softc *sc;
+	uint32_t rdval;
 
-	err = clkdom_finit(sc->clkdom);
-	if (err) {
-		DPRINTF(sc->sc_dev, "Clk domain finit fails %x.\n", err);
-		return (ENXIO);
-	}
+	sc = device_get_softc(dev);
 
+	rdval = SYSCON_UNLOCKED_READ_4(sc->syscon, addr);
+	*val = rdval;
+	DPRINTF(sc->dev, "ti_divider_clkdev_read_4: addr %x val %x\n",
+	     addr, *val);
 	return (0);
 }
 
+static int
+ti_divider_clkdev_modify_4(device_t dev, bus_addr_t addr,
+    uint32_t clear_mask, uint32_t set_mask)
+{
+	struct ti_divider_softc *sc;
+
+	sc = device_get_softc(dev);
+	DPRINTF(sc->dev, "ti_divider_clkdev_modify_4: addr %x clear %x set %x\n",
+	    addr, clear_mask, set_mask);
+	return (SYSCON_UNLOCKED_MODIFY_4(sc->syscon, addr, clear_mask,
+	    set_mask));
+}
+
+static void
+ti_divider_clkdev_device_lock(device_t dev)
+{
+	struct ti_divider_softc *sc;
+
+	sc = device_get_softc(dev);
+	DPRINTF(sc->dev, "ti_divider_clkdev_device_lock\n");
+	SYSCON_DEVICE_LOCK(sc->syscon->pdev);
+}
+
+static void
+ti_divider_clkdev_device_unlock(device_t dev)
+{
+	struct ti_divider_softc *sc;
+
+	sc = device_get_softc(dev);
+	DPRINTF(sc->dev, "ti_divider_clkdev_device_unlock\n");
+	SYSCON_DEVICE_UNLOCK(sc->syscon->pdev);
+}
+
 static int
 ti_divider_probe(device_t dev)
 {
@@ -111,6 +149,8 @@
 		return (ENXIO);
 
 	device_set_desc(dev, "TI Divider Clock");
+	if (bootverbose == 0)
+		device_quiet(dev);
 
 	return (BUS_PROBE_DEFAULT);
 }
@@ -120,17 +160,33 @@
 {
 	struct ti_divider_softc *sc;
 	phandle_t	node;
-	int		err;
+	int		err, index;
 	cell_t		value;
 	uint32_t	ti_max_div;
+	const char	*node_name;
 
 	sc = device_get_softc(dev);
-	sc->sc_dev = dev;
+	sc->dev = dev;
 	node = ofw_bus_get_node(dev);
 
-	/* Grab the content of reg properties */
-	OF_getencprop(node, "reg", &value, sizeof(value));
-	sc->div_def.offset = value;
+	err = SYSCON_GET_HANDLE(dev, &sc->syscon);
+	if (err != 0) {
+		panic("Cannot get syscon handle.\n");
+	}
+
+	clk_parse_ofw_clk_name(dev, node, &node_name);
+	if (node_name == NULL) {
+		panic("Cannot get name of the clock node");
+	}
+
+	/* Get the content of reg properties */
+	if (OF_hasprop(node, "reg") == 1) {
+		OF_getencprop(node, "reg", &value, sizeof(value));
+		sc->div_def.offset = value;
+	} else {
+		/* assume parent is clksel... */
+		sc->div_def.offset = ti_clksel_get_reg(device_get_parent(dev));
+	}
 
 	if (OF_hasprop(node, "ti,bit-shift")) {
 		OF_getencprop(node, "ti,bit-shift", &value, sizeof(value));
@@ -143,7 +199,8 @@
 
 	if (OF_hasprop(node, "ti,index-power-of-two")) {
 		/* FIXME: later */
-		device_printf(sc->sc_dev, "ti,index-power-of-two - Not implemented\n");
+		DPRINTF(sc->dev,
+		    "ti,index-power-of-two - Not implemented\n");
 		/* remember to update i_width a few lines below */
 	}
 	if (OF_hasprop(node, "ti,max-div")) {
@@ -152,18 +209,21 @@
 	}
 
 	if (OF_hasprop(node, "clock-output-names"))
-		device_printf(sc->sc_dev, "clock-output-names\n");
+		DPRINTF(sc->dev, "clock-output-names\n");
 	if (OF_hasprop(node, "ti,dividers"))
-		device_printf(sc->sc_dev, "ti,dividers\n");
+		DPRINTF(sc->dev, "ti,dividers\n");
 	if (OF_hasprop(node, "ti,min-div"))
-		device_printf(sc->sc_dev, "ti,min-div - Not implemented\n");
+		DPRINTF(sc->dev, "ti,min-div - Not implemented\n");
 
 	if (OF_hasprop(node, "ti,autoidle-shift"))
-		device_printf(sc->sc_dev, "ti,autoidle-shift - Not implemented\n");
+		DPRINTF(sc->dev,
+		   "ti,autoidle-shift - Not implemented\n");
 	if (OF_hasprop(node, "ti,set-rate-parent"))
-		device_printf(sc->sc_dev, "ti,set-rate-parent - Not implemented\n");
+		DPRINTF(sc->dev,
+		    "ti,set-rate-parent - Not implemented\n");
 	if (OF_hasprop(node, "ti,latch-bit"))
-		device_printf(sc->sc_dev, "ti,latch-bit - Not implemented\n");
+		DPRINTF(sc->dev,
+		    "ti,latch-bit - Not implemented\n");
 
 	/* Figure out the width from ti_max_div */
 	if (sc->div_def.div_flags)
@@ -171,33 +231,46 @@
 	else
 		sc->div_def.i_width = fls(ti_max_div);
 
-	DPRINTF(sc->sc_dev, "div_def.i_width %x\n", sc->div_def.i_width);
+	DPRINTF(sc->dev, "div_def.i_width %x\n", sc->div_def.i_width);
 
-	read_clock_cells(sc->sc_dev, &sc->clock_cell);
-
-	create_clkdef(sc->sc_dev, &sc->clock_cell, &sc->div_def.clkdef);
+	/* Find parent in lookup table */
+	for (index = 0; index < nitems(div_parent_table); index++) {
+		if (strcmp(node_name, div_parent_table[index].node_name) == 0)
+			break;
+	}
 
-	err = find_parent_clock_names(sc->sc_dev, &sc->clock_cell, &sc->div_def.clkdef);
+	if (index == nitems(div_parent_table))
+		panic("Cant find clock %s\n", node_name);
 
-	if (err) {
-		/* free_clkdef will be called in ti_divider_new_pass */
-		DPRINTF(sc->sc_dev, "find_parent_clock_names failed\n");
-		return (bus_generic_attach(sc->sc_dev));
-	}
+	DPRINTF(sc->dev, "%s at div_parent_table[%d]\n", node_name, index);
 
-	err = register_clk(sc);
+	/* Fill clknode_init_def */
+	sc->div_def.clkdef.id = 1;
+	sc->div_def.clkdef.flags = CLK_NODE_STATIC_STRINGS;
+	sc->div_def.clkdef.name = div_parent_table[index].node_name;
+	sc->div_def.clkdef.parent_cnt = div_parent_table[index].parent_cnt;
+	sc->div_def.clkdef.parent_names =
+		div_parent_table[index].parent_names;
 
-	if (err) {
-		/* free_clkdef will be called in ti_divider_new_pass */
-		DPRINTF(sc->sc_dev, "register_clk failed\n");
-		return (bus_generic_attach(sc->sc_dev));
+	sc->clkdom = clkdom_create(sc->dev);
+	if (sc->clkdom == NULL) {
+		DPRINTF(sc->dev, "Failed to create clkdom\n");
+		return (ENXIO);
 	}
 
-	sc->attach_done = true;
+	err = clknode_div_register(sc->clkdom, &sc->div_def);
+	if (err != 0) {
+		DPRINTF(sc->dev, "clknode_div_register failed %x\n", err);
+		return (ENXIO);
+	}
 
-	free_clkdef(&sc->div_def.clkdef);
+	err = clkdom_finit(sc->clkdom);
+	if (err != 0) {
+		DPRINTF(sc->dev, "Clk domain finit fails %x.\n", err);
+		return (ENXIO);
+	}
 
-	return (bus_generic_attach(sc->sc_dev));
+	return (bus_generic_attach(sc->dev));
 }
 
 static int
@@ -206,45 +279,18 @@
 	return (EBUSY);
 }
 
-static void
-ti_divider_new_pass(device_t dev)
-{
-	struct ti_divider_softc *sc;
-	int err;
-
-	sc = device_get_softc(dev);
-
-	if (sc->attach_done) {
-		return;
-	}
-
-	err = find_parent_clock_names(sc->sc_dev, &sc->clock_cell, &sc->div_def.clkdef);
-	if (err) {
-		/* free_clkdef will be called in a later call to ti_divider_new_pass */
-		DPRINTF(sc->sc_dev, "new_pass find_parent_clock_names failed\n");
-		return;
-	}
-
-	err = register_clk(sc);
-	if (err) {
-		/* free_clkdef will be called in a later call to ti_divider_new_pass */
-		DPRINTF(sc->sc_dev, "new_pass register_clk failed\n");
-		return;
-	}
-
-	sc->attach_done = true;
-
-	free_clkdef(&sc->div_def.clkdef);
-}
-
 static device_method_t ti_divider_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		ti_divider_probe),
 	DEVMETHOD(device_attach,	ti_divider_attach),
 	DEVMETHOD(device_detach,	ti_divider_detach),
 
-	/* Bus interface */
-	DEVMETHOD(bus_new_pass,		ti_divider_new_pass),
+	/* Clock device interface */
+	DEVMETHOD(clkdev_device_lock,	ti_divider_clkdev_device_lock),
+	DEVMETHOD(clkdev_device_unlock,	ti_divider_clkdev_device_unlock),
+	DEVMETHOD(clkdev_read_4,	ti_divider_clkdev_read_4),
+	DEVMETHOD(clkdev_write_4,	ti_divider_clkdev_write_4),
+	DEVMETHOD(clkdev_modify_4,	ti_divider_clkdev_modify_4),
 
 	DEVMETHOD_END
 };
diff --git a/sys/arm/ti/clk/ti_dpll_clock.c b/sys/arm/ti/clk/ti_dpll_clock.c
--- a/sys/arm/ti/clk/ti_dpll_clock.c
+++ b/sys/arm/ti/clk/ti_dpll_clock.c
@@ -25,6 +25,11 @@
  * SUCH DAMAGE.
  */
 
+/*
+ * Devicetree description
+ * Documentation/devicetree/bindings/clock/ti/dpll.txt
+ */
+
 #include <sys/param.h>
 #include <sys/conf.h>
 #include <sys/bus.h>
@@ -40,8 +45,9 @@
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
+#include <arm/ti/clk/am33xx.h>
 #include <arm/ti/clk/ti_clk_dpll.h>
-#include "clock_common.h"
+#include <arm/ti/clk/ti_clock_common.h>
 
 #if 0
 #define DPRINTF(dev, msg...) device_printf(dev, msg)
@@ -49,19 +55,12 @@
 #define DPRINTF(dev, msg...)
 #endif
 
-/*
- * Devicetree description
- * Documentation/devicetree/bindings/clock/ti/dpll.txt
- */
-
 struct ti_dpll_softc {
 	device_t		dev;
 	uint8_t			dpll_type;
 
-	bool			attach_done;
 	struct ti_clk_dpll_def	dpll_def;
 
-	struct clock_cell_info	clock_cell;
 	struct clkdom		*clkdom;
 };
 
@@ -109,32 +108,6 @@
 	{ NULL,				TI_DPLL_END }
 };
 
-static int
-register_clk(struct ti_dpll_softc *sc) {
-	int err;
-
-	sc->clkdom = clkdom_create(sc->dev);
-	if (sc->clkdom == NULL) {
-		DPRINTF(sc->dev, "Failed to create clkdom\n");
-		return (ENXIO);
-	}
-
-	err = ti_clknode_dpll_register(sc->clkdom, &sc->dpll_def);
-	if (err) {
-		DPRINTF(sc->dev,
-			"ti_clknode_dpll_register failed %x\n", err);
-		return (ENXIO);
-	}
-
-	err = clkdom_finit(sc->clkdom);
-	if (err) {
-		DPRINTF(sc->dev, "Clk domain finit fails %x.\n", err);
-		return (ENXIO);
-	}
-
-	return (0);
-}
-
 static int
 ti_dpll_probe(device_t dev)
 {
@@ -145,6 +118,8 @@
 		return (ENXIO);
 
 	device_set_desc(dev, "TI DPLL Clock");
+	if (bootverbose == 0)
+		device_quiet(dev);
 
 	return (BUS_PROBE_DEFAULT);
 }
@@ -154,7 +129,7 @@
 	ssize_t numbytes_regs;
 	uint32_t num_regs;
 	phandle_t node;
-	cell_t reg_cells[4];
+	cell_t reg_cells[6];
 
 	if (sc->dpll_type == TI_AM3_DPLL_X2_CLOCK ||
 		sc->dpll_type == TI_OMAP4_DPLL_X2_CLOCK) {
@@ -172,7 +147,7 @@
 	num_regs = numbytes_regs / sizeof(cell_t);
 
 	/* Sanity check */
-	if (num_regs > 4)
+	if (num_regs > 6)
 		return (ENXIO);
 
 	OF_getencprop(node, "reg", reg_cells, numbytes_regs);
@@ -184,11 +159,12 @@
 		case TI_AM3_DPLL_CLOCK:
 		case TI_AM3_DPLL_CORE_CLOCK:
 		case TI_AM3_DPLL_X2_CLOCK:
-			if (num_regs != 3)
-				return (ENXIO);
 			sc->dpll_def.ti_clkmode_offset = reg_cells[0];
 			sc->dpll_def.ti_idlest_offset = reg_cells[1];
 			sc->dpll_def.ti_clksel_offset = reg_cells[2];
+			/* Do not have autoidle */
+			sc->dpll_def.ti_ssc_deltam_offset = reg_cells[3];
+			sc->dpll_def.ti_ssc_modfreq_offset = reg_cells[4];
 			break;
 
 		case TI_OMAP2_DPLL_CORE_CLOCK:
@@ -203,6 +179,8 @@
 			sc->dpll_def.ti_idlest_offset = reg_cells[1];
 			sc->dpll_def.ti_clksel_offset = reg_cells[2];
 			sc->dpll_def.ti_autoidle_offset = reg_cells[3];
+			sc->dpll_def.ti_ssc_deltam_offset = reg_cells[4];
+			sc->dpll_def.ti_ssc_modfreq_offset = reg_cells[5];
 			break;
 	}
 
@@ -256,9 +234,10 @@
 static int
 ti_dpll_attach(device_t dev)
 {
-	struct ti_dpll_softc *sc;
-	phandle_t node;
-	int err;
+	struct ti_dpll_softc	*sc;
+	phandle_t		node;
+	int			err, index;
+	const char 		*node_name;
 
 	sc = device_get_softc(dev);
 	sc->dev = dev;
@@ -266,6 +245,11 @@
 	sc->dpll_type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
 	node = ofw_bus_get_node(dev);
 
+	clk_parse_ofw_clk_name(dev, node, &node_name);
+	if (node_name == NULL) {
+		panic("Cannot get name of the clock node");
+	}
+
 	/* Grab the content of reg properties */
 	parse_dpll_reg(sc);
 
@@ -281,31 +265,52 @@
 	if (OF_hasprop(node, "ti,lock")) {
 		sc->dpll_def.ti_clkmode_flags |= LOCK_MODE_FLAG;
 	}
+	if (OF_hasprop(node, "ti,min-div")) {
+	}
+	if (OF_hasprop(node, "ti,ssc-deltam")) {
+	}
+	if (OF_hasprop(node, "ti,ssc-modfreq-hz")) {
+	}
+	if (OF_hasprop(node, "ti,ssc-downspread")) {
+	}
 
-	read_clock_cells(sc->dev, &sc->clock_cell);
-
-	create_clkdef(sc->dev, &sc->clock_cell, &sc->dpll_def.clkdef);
+	/* Find parent in lookup table */
+	for (index = 0; index < nitems(dpll_parent_table); index++) {
+		if (strcmp(node_name, dpll_parent_table[index].node_name) == 0)
+			break;
+	}
 
-	err = find_parent_clock_names(sc->dev, &sc->clock_cell,
-			&sc->dpll_def.clkdef);
+	if (index == nitems(dpll_parent_table))
+		panic("Cant find clock %s\n", node_name);
 
-	if (err) {
-		/* free_clkdef will be called in ti_dpll_new_pass */
-		DPRINTF(sc->dev, "find_parent_clock_names failed\n");
-		return (bus_generic_attach(sc->dev));
-	}
+	DPRINTF(sc->dev, "%s at dpll_parent_table[%d]\n", node_name, index);
 
-	err = register_clk(sc);
+	/* Fill clknode_init_def */
+	sc->dpll_def.clkdef.id = 1;
+	sc->dpll_def.clkdef.name = dpll_parent_table[index].node_name;
+	sc->dpll_def.clkdef.parent_cnt = dpll_parent_table[index].parent_cnt;
+	sc->dpll_def.clkdef.parent_names =
+		dpll_parent_table[index].parent_names;
+	sc->dpll_def.clkdef.flags = CLK_NODE_STATIC_STRINGS;
 
-	if (err) {
-		/* free_clkdef will be called in ti_dpll_new_pass */
-		DPRINTF(sc->dev, "register_clk failed\n");
-		return (bus_generic_attach(sc->dev));
+	sc->clkdom = clkdom_create(sc->dev);
+	if (sc->clkdom == NULL) {
+		DPRINTF(sc->dev, "Failed to create clkdom\n");
+		return (ENXIO);
 	}
 
-	sc->attach_done = true;
+	err = ti_clknode_dpll_register(sc->clkdom, &sc->dpll_def);
+	if (err != 0) {
+		DPRINTF(sc->dev,
+			"ti_clknode_dpll_register failed %x\n", err);
+		return (ENXIO);
+	}
 
-	free_clkdef(&sc->dpll_def.clkdef);
+	err = clkdom_finit(sc->clkdom);
+	if (err != 0) {
+		DPRINTF(sc->dev, "Clk domain finit fails %x.\n", err);
+		return (ENXIO);
+	}
 
 	return (bus_generic_attach(sc->dev));
 }
@@ -316,47 +321,12 @@
 	return (EBUSY);
 }
 
-static void
-ti_dpll_new_pass(device_t dev)
-{
-	struct ti_dpll_softc *sc;
-	int err;
-
-	sc = device_get_softc(dev);
-
-	if (sc->attach_done) {
-		return;
-	}
-
-	err = find_parent_clock_names(sc->dev, &sc->clock_cell,
-		&sc->dpll_def.clkdef);
-	if (err) {
-		/* free_clkdef will be called in a later call to ti_dpll_new_pass */
-		DPRINTF(sc->dev,
-			"new_pass find_parent_clock_names failed\n");
-		return;
-	}
-
-	err = register_clk(sc);
-	if (err) {
-		/* free_clkdef will be called in a later call to ti_dpll_new_pass */
-		DPRINTF(sc->dev, "new_pass register_clk failed\n");
-		return;
-	}
-
-	sc->attach_done = true;
-	free_clkdef(&sc->dpll_def.clkdef);
-}
-
 static device_method_t ti_dpll_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		ti_dpll_probe),
 	DEVMETHOD(device_attach,	ti_dpll_attach),
 	DEVMETHOD(device_detach,	ti_dpll_detach),
 
-	/* Bus interface */
-	DEVMETHOD(bus_new_pass,		ti_dpll_new_pass),
-
 	DEVMETHOD_END
 };
 
diff --git a/sys/arm/ti/clk/ti_gate_clock.c b/sys/arm/ti/clk/ti_gate_clock.c
--- a/sys/arm/ti/clk/ti_gate_clock.c
+++ b/sys/arm/ti/clk/ti_gate_clock.c
@@ -25,6 +25,11 @@
  * SUCH DAMAGE.
  */
 
+/*
+ * Devicetree description
+ * Documentation/devicetree/bindings/clock/ti/gate.txt
+ */
+
 #include <sys/param.h>
 #include <sys/conf.h>
 #include <sys/bus.h>
@@ -36,11 +41,16 @@
 #include <machine/bus.h>
 #include <dev/fdt/simplebus.h>
 
-#include <dev/clk/clk_gate.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
+#include <dev/clk/clk_gate.h>
+#include <dev/syscon/syscon.h>
 
-#include "clock_common.h"
+#include <arm/ti/clk/am33xx.h>
+#include <arm/ti/clk/ti_clock_common.h>
+#include <arm/ti/clk/ti_clksel.h>
+#include "clkdev_if.h"
+#include "syscon_if.h"
 
 #define DEBUG_GATE	0
 
@@ -50,19 +60,13 @@
 #define DPRINTF(dev, msg...)
 #endif
 
-/*
- * Devicetree description
- * Documentation/devicetree/bindings/clock/ti/gate.txt
- */
-
 struct ti_gate_softc {
-	device_t		sc_dev;
-	bool			attach_done;
+	device_t		dev;
 	uint8_t			sc_type;
 
 	struct clk_gate_def	gate_def;
-	struct clock_cell_info  clock_cell;
 	struct clkdom		*clkdom;
+	struct syscon		*syscon;
 };
 
 static int ti_gate_probe(device_t dev);
@@ -83,12 +87,70 @@
 	{ "ti,wait-gate-clock",			TI_WAIT_GATE_CLOCK },
 	{ "ti,dss-gate-clock",			TI_DSS_GATE_CLOCK },
 	{ "ti,am35xx-gate-clock",		TI_AM35XX_GATE_CLOCK },
-	{ "ti,clkdm-gate-clock",		TI_CLKDM_GATE_CLOCK },
+	/* For now, dont support clkdm-gate-clock */
+	/* { "ti,clkdm-gate-clock",		TI_CLKDM_GATE_CLOCK }, */
 	{ "ti,hsdiv-gate-cloc",			TI_HSDIV_GATE_CLOCK },
-	{ "ti,composite-no-wait-gate-clock",	TI_COMPOSITE_NO_WAIT_GATE_CLOCK },
+	{ "ti,composite-no-wait-gate-clock", TI_COMPOSITE_NO_WAIT_GATE_CLOCK },
 	{ NULL,					TI_GATE_END }
 };
 
+static int
+ti_gate_clkdev_write_4(device_t dev, bus_addr_t addr, uint32_t val)
+{
+	struct ti_gate_softc *sc;
+
+	sc = device_get_softc(dev);
+	DPRINTF(sc->dev, "gate_clkdev_write_4: addr %x val %x\n",
+	    addr, val);
+	return (SYSCON_UNLOCKED_WRITE_4(sc->syscon, addr, val));
+}
+
+static int
+ti_gate_clkdev_read_4(device_t dev, bus_addr_t addr, uint32_t *val)
+{
+	struct ti_gate_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	*val = SYSCON_UNLOCKED_READ_4(sc->syscon, addr);
+	DPRINTF(sc->dev, "gate_clkdev_write_4: addr %x val %x\n",
+	     addr, *val);
+	return (0);
+}
+
+static int
+ti_gate_clkdev_modify_4(device_t dev, bus_addr_t addr,
+    uint32_t clear_mask, uint32_t set_mask)
+{
+	struct ti_gate_softc *sc;
+
+	sc = device_get_softc(dev);
+	DPRINTF(sc->dev, "clkdev_modify_4: addr %x clear_mask %x set_mask %x\n",
+	     addr, clear_mask, set_mask);
+	return (SYSCON_UNLOCKED_MODIFY_4(sc->syscon, addr, clear_mask,
+	    set_mask));
+}
+
+static void
+ti_gate_clkdev_device_lock(device_t dev)
+{
+	struct ti_gate_softc *sc;
+
+	sc = device_get_softc(dev);
+	DPRINTF(sc->dev, "ti_gate_clkdev_device_lock\n");
+	SYSCON_DEVICE_LOCK(sc->syscon->pdev);
+}
+
+static void
+ti_gate_clkdev_device_unlock(device_t dev)
+{
+	struct ti_gate_softc *sc;
+
+	sc = device_get_softc(dev);
+	DPRINTF(sc->dev, "ti_gate_clkdev_device_unlock\n");
+	SYSCON_DEVICE_UNLOCK(sc->syscon->pdev);
+}
+
 static int
 ti_gate_probe(device_t dev)
 {
@@ -99,108 +161,113 @@
 		return (ENXIO);
 
 	device_set_desc(dev, "TI Gate Clock");
+	if (bootverbose == 0)
+		device_quiet(dev);
 
 	return (BUS_PROBE_DEFAULT);
 }
 
-static int
-register_clk(struct ti_gate_softc *sc) {
-	int err;
-	sc->clkdom = clkdom_create(sc->sc_dev);
-	if (sc->clkdom == NULL) {
-		DPRINTF(sc->sc_dev, "Failed to create clkdom\n");
-		return ENXIO;
-	}
-
-	err = clknode_gate_register(sc->clkdom, &sc->gate_def);
-	if (err) {
-		DPRINTF(sc->sc_dev, "clknode_gate_register failed %x\n", err);
-		return ENXIO;
-	}
-
-	err = clkdom_finit(sc->clkdom);
-	if (err) {
-		DPRINTF(sc->sc_dev, "Clk domain finit fails %x.\n", err);
-		return ENXIO;
-	}
-
-	return (0);
-}
-
 static int
 ti_gate_attach(device_t dev)
 {
 	struct ti_gate_softc *sc;
-	phandle_t node;
-	int err;
-	cell_t value;
+	phandle_t	node;
+	int		err, index;
+	cell_t 		value;
+	const char	*node_name;
 
 	sc = device_get_softc(dev);
-	sc->sc_dev = dev;
+	sc->dev = dev;
 	node = ofw_bus_get_node(dev);
 
+	/* Get syscon */
+	err = SYSCON_GET_HANDLE(dev, &sc->syscon);
+	if (err != 0) {
+		panic("Cannot get syscon handle.\n");
+	}
+
+	clk_parse_ofw_clk_name(dev, node, &node_name);
+	if (node_name == NULL) {
+		panic("Cannot get name of the clock node");
+	}
+
 	/* Get the compatible type */
 	sc->sc_type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
 
 	/* Get the content of reg properties */
-	if (sc->sc_type != TI_CLKDM_GATE_CLOCK) {
+	if (OF_hasprop(node, "reg") == 1) {
 		OF_getencprop(node, "reg", &value, sizeof(value));
 		sc->gate_def.offset = value;
+	} else {
+		/* assume parent is clksel... */
+		sc->gate_def.offset = ti_clksel_get_reg(device_get_parent(dev));
 	}
-#if DEBUG_GATE
-	else {
-		DPRINTF(sc->sc_dev, "no reg (TI_CLKDM_GATE_CLOCK)\n");
-	}
-#endif
 
 	if (OF_hasprop(node, "ti,bit-shift")) {
 		OF_getencprop(node, "ti,bit-shift", &value, sizeof(value));
 		sc->gate_def.shift = value;
-		DPRINTF(sc->sc_dev, "ti,bit-shift => shift %x\n", sc->gate_def.shift);
+		DPRINTF(sc->dev, "ti,bit-shift => shift %x\n",
+		    sc->gate_def.shift);
 	}
 	if (OF_hasprop(node, "ti,set-bit-to-disable")) {
 		sc->gate_def.on_value = 0;
 		sc->gate_def.off_value = 1;
-		DPRINTF(sc->sc_dev,
-			"on_value = 0, off_value = 1 (ti,set-bit-to-disable)\n");
+		DPRINTF(sc->dev,
+			"ti,set-bit-to-disable (on = 0, off = 1)\n");
 	} else {
 		sc->gate_def.on_value = 1;
 		sc->gate_def.off_value = 0;
-		DPRINTF(sc->sc_dev, "on_value = 1, off_value = 0\n");
+		DPRINTF(sc->dev,
+			"!ti,set-bit-to-disable (on = 1, off = 0)\n");
 	}
 
 	sc->gate_def.gate_flags = 0x0;
 
-	read_clock_cells(sc->sc_dev, &sc->clock_cell);
 
-	create_clkdef(sc->sc_dev, &sc->clock_cell, &sc->gate_def.clkdef);
+	/* Find parent in lookup table */
+	for (index = 0; index < nitems(gate_parent_table); index++) {
+		if (strcmp(node_name, gate_parent_table[index].node_name) == 0)
+			break;
+	}
 
-	/* Calculate mask */
-	sc->gate_def.mask = (1 << fls(sc->clock_cell.num_real_clocks)) - 1;
-	DPRINTF(sc->sc_dev, "num_real_clocks %x gate_def.mask %x\n",
-		sc->clock_cell.num_real_clocks, sc->gate_def.mask);
+	if (index == nitems(gate_parent_table))
+		panic("Cant find clock %s\n", node_name);
 
-	err = find_parent_clock_names(sc->sc_dev, &sc->clock_cell, &sc->gate_def.clkdef);
+	DPRINTF(dev, "%s at gate_parent_table[%d]\n",
+		node_name, index);
 
-	if (err) {
-		/* free_clkdef will be called in ti_gate_new_pass */
-		DPRINTF(sc->sc_dev, "find_parent_clock_names failed\n");
-		return (bus_generic_attach(sc->sc_dev));
-	}
+	/* Fill clknode_init_def */
+	sc->gate_def.clkdef.id = 1;
+	sc->gate_def.clkdef.flags = CLK_NODE_STATIC_STRINGS;
+	sc->gate_def.clkdef.name = gate_parent_table[index].node_name;
+	sc->gate_def.clkdef.parent_cnt = gate_parent_table[index].parent_cnt;
+	sc->gate_def.clkdef.parent_names =gate_parent_table[index].parent_names;
 
-	err = register_clk(sc);
+	/* Calculate mask */
+	sc->gate_def.mask = (1 << fls(sc->gate_def.clkdef.parent_cnt)) - 1;
+	DPRINTF(sc->dev, "num_real_clocks %x gate_def.mask %x\n",
+		sc->gate_def.clkdef.parent_cnt,
+		sc->gate_def.mask);
 
-	if (err) {
-		/* free_clkdef will be called in ti_gate_new_pass */
-		DPRINTF(sc->sc_dev, "register_clk failed\n");
-		return (bus_generic_attach(sc->sc_dev));
+	sc->clkdom = clkdom_create(sc->dev);
+	if (sc->clkdom == NULL) {
+		DPRINTF(sc->dev, "Failed to create clkdom\n");
+		return ENXIO;
 	}
 
-	sc->attach_done = true;
+	err = clknode_gate_register(sc->clkdom, &sc->gate_def);
+	if (err != 0) {
+		DPRINTF(sc->dev, "clknode_gate_register failed %x\n", err);
+		return ENXIO;
+	}
 
-	free_clkdef(&sc->gate_def.clkdef);
+	err = clkdom_finit(sc->clkdom);
+	if (err != 0) {
+		DPRINTF(sc->dev, "Clk domain finit fails %x.\n", err);
+		return ENXIO;
+	}
 
-	return (bus_generic_attach(sc->sc_dev));
+	return (bus_generic_attach(sc->dev));
 }
 
 static int
@@ -209,44 +276,18 @@
 	return (EBUSY);
 }
 
-static void
-ti_gate_new_pass(device_t dev) {
-	struct ti_gate_softc *sc;
-	int err;
-
-	sc = device_get_softc(dev);
-
-	if (sc->attach_done) {
-		return;
-	}
-
-	err = find_parent_clock_names(sc->sc_dev, &sc->clock_cell, &sc->gate_def.clkdef);
-	if (err) {
-		/* free_clkdef will be called in later call to ti_gate_new_pass */
-		DPRINTF(sc->sc_dev, "new_pass find_parent_clock_names failed\n");
-		return;
-	}
-
-	err = register_clk(sc);
-	if (err) {
-		/* free_clkdef will be called in later call to ti_gate_new_pass */
-		DPRINTF(sc->sc_dev, "new_pass register_clk failed\n");
-		return;
-	}
-
-	sc->attach_done = true;
-
-	free_clkdef(&sc->gate_def.clkdef);
-}
-
 static device_method_t ti_gate_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		ti_gate_probe),
 	DEVMETHOD(device_attach,	ti_gate_attach),
 	DEVMETHOD(device_detach,	ti_gate_detach),
 
-	/* Bus interface */
-	DEVMETHOD(bus_new_pass,		ti_gate_new_pass),
+	/* Clock device interface */
+	DEVMETHOD(clkdev_device_lock,	ti_gate_clkdev_device_lock),
+	DEVMETHOD(clkdev_device_unlock,	ti_gate_clkdev_device_unlock),
+	DEVMETHOD(clkdev_read_4,	ti_gate_clkdev_read_4),
+	DEVMETHOD(clkdev_write_4,	ti_gate_clkdev_write_4),
+	DEVMETHOD(clkdev_modify_4,	ti_gate_clkdev_modify_4),
 
 	DEVMETHOD_END
 };
diff --git a/sys/arm/ti/clk/ti_mux_clock.c b/sys/arm/ti/clk/ti_mux_clock.c
--- a/sys/arm/ti/clk/ti_mux_clock.c
+++ b/sys/arm/ti/clk/ti_mux_clock.c
@@ -25,6 +25,11 @@
  * SUCH DAMAGE.
  */
 
+/*
+ * Devicetree description
+ * Documentation/devicetree/bindings/clock/ti/mux.txt
+ */
+
 #include <sys/param.h>
 #include <sys/conf.h>
 #include <sys/bus.h>
@@ -39,10 +44,16 @@
 #include <dev/fdt/simplebus.h>
 
 #include <dev/clk/clk_mux.h>
+#include <dev/syscon/syscon.h>
+
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
-#include "clock_common.h"
+#include <arm/ti/clk/am33xx.h>
+#include <arm/ti/clk/ti_clock_common.h>
+#include <arm/ti/clk/ti_clksel.h>
+#include "clkdev_if.h"
+#include "syscon_if.h"
 
 #if 0
 #define DPRINTF(dev, msg...) device_printf(dev, msg)
@@ -50,18 +61,12 @@
 #define DPRINTF(dev, msg...)
 #endif
 
-/*
- * Devicetree description
- * Documentation/devicetree/bindings/clock/ti/mux.txt
- */
-
 struct ti_mux_softc {
-	device_t		sc_dev;
-	bool			attach_done;
+	device_t		dev;
 
 	struct clk_mux_def	mux_def;
-	struct clock_cell_info	clock_cell;
 	struct clkdom 		*clkdom;
+	struct syscon		*syscon;
 };
 
 static int ti_mux_probe(device_t dev);
@@ -79,141 +84,179 @@
 };
 
 static int
-ti_mux_probe(device_t dev)
+ti_mux_clkdev_write_4(device_t dev, bus_addr_t addr, uint32_t val)
 {
-	if (!ofw_bus_status_okay(dev))
-		return (ENXIO);
+	struct ti_mux_softc *sc;
 
-	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
-		return (ENXIO);
+	sc = device_get_softc(dev);
+	DPRINTF(sc->dev, "mux_clkdev_write_4: addr %x val %x\n",
+	     addr, val);
+	return (SYSCON_UNLOCKED_WRITE_4(sc->syscon, addr, val));
+}
 
-	device_set_desc(dev, "TI Mux Clock");
+static int
+ti_mux_clkdev_read_4(device_t dev, bus_addr_t addr, uint32_t *val)
+{
+	struct ti_mux_softc *sc;
+	uint32_t rdval;
 
-	return (BUS_PROBE_DEFAULT);
+	sc = device_get_softc(dev);
+
+	rdval = SYSCON_UNLOCKED_READ_4(sc->syscon, addr);
+	*val = rdval;
+	DPRINTF(sc->dev, "clkdev_read_4: addr %x val %x\n",
+	    addr, *val);
+	return (0);
 }
 
 static int
-register_clk(struct ti_mux_softc *sc) {
-	int err;
+ti_mux_clkdev_modify_4(device_t dev, bus_addr_t addr,
+    uint32_t clear_mask, uint32_t set_mask)
+{
+	struct ti_mux_softc *sc;
 
-	sc->clkdom = clkdom_create(sc->sc_dev);
-	if (sc->clkdom == NULL) {
-		DPRINTF(sc->sc_dev, "Failed to create clkdom\n");
-		return ENXIO;
-	}
+	sc = device_get_softc(dev);
+	DPRINTF(sc->dev, "clkdev_modify_4: addr %x clear %x mask %x\n",
+	    addr, clear_mask, set_mask);
+	return (SYSCON_UNLOCKED_MODIFY_4(sc->syscon, addr, clear_mask,
+	    set_mask));
+}
 
-	err = clknode_mux_register(sc->clkdom, &sc->mux_def);
-	if (err) {
-		DPRINTF(sc->sc_dev, "clknode_mux_register failed %x\n", err);
-		return ENXIO;
-	}
+static void
+ti_mux_clkdev_device_lock(device_t dev)
+{
+	struct ti_mux_softc *sc;
 
-	err = clkdom_finit(sc->clkdom);
-	if (err) {
-		DPRINTF(sc->sc_dev, "Clk domain finit fails %x.\n", err);
-		return ENXIO;
-	}
+	sc = device_get_softc(dev);
+	DPRINTF(sc->dev, "ti_mux_clkdev_device_lock\n");
+	SYSCON_DEVICE_LOCK(sc->syscon->pdev);
+}
+
+static void
+ti_mux_clkdev_device_unlock(device_t dev)
+{
+	struct ti_mux_softc *sc;
+
+	sc = device_get_softc(dev);
+	DPRINTF(sc->dev, "ti_mux_clkdev_device_unlock\n");
+	SYSCON_DEVICE_UNLOCK(sc->syscon->pdev);
+}
+
+static int
+ti_mux_probe(device_t dev)
+{
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "TI Mux Clock");
+	if (bootverbose == 0)
+		device_quiet(dev);
 
-	return 0;
+	return (BUS_PROBE_DEFAULT);
 }
 
 static int
 ti_mux_attach(device_t dev)
 {
 	struct ti_mux_softc *sc;
-	phandle_t node;
-	int err;
-	cell_t value;
+	phandle_t	node;
+	int		err, index;
+	cell_t		value;
+	const char 	*node_name;
 
 	sc = device_get_softc(dev);
-	sc->sc_dev = dev;
+	sc->dev = dev;
 	node = ofw_bus_get_node(dev);
 
+	err = SYSCON_GET_HANDLE(device_get_parent(dev), &sc->syscon);
+	if (err != 0) {
+		panic("Cannot get syscon handle.\n");
+	}
+
+	clk_parse_ofw_clk_name(dev, node, &node_name);
+	if (node_name == NULL) {
+		panic("Cannot get name of the clock node");
+	}
+
 	/* Grab the content of reg properties */
-	OF_getencprop(node, "reg", &value, sizeof(value));
-	sc->mux_def.offset = value;
+	if (OF_hasprop(node, "reg") == 1) {
+		OF_getencprop(node, "reg", &value, sizeof(value));
+		sc->mux_def.offset = value;
+	} else {
+		/* assume parent is clksel... */
+		sc->mux_def.offset = ti_clksel_get_reg(device_get_parent(dev));
+	}
 
 	if (OF_hasprop(node, "ti,bit-shift")) {
 		OF_getencprop(node, "ti,bit-shift", &value, sizeof(value));
 		sc->mux_def.shift = value;
-		DPRINTF(sc->sc_dev, "ti,bit-shift => shift %x\n", sc->mux_def.shift);
+		DPRINTF(sc->dev, "ti,bit-shift => shift %x\n",
+		    sc->mux_def.shift);
 	}
 	if (OF_hasprop(node, "ti,index-starts-at-one")) {
 		/* FIXME: Add support in dev/extres/clk */
 		/*sc->mux_def.mux_flags =  ... */
-		device_printf(sc->sc_dev, "ti,index-starts-at-one - Not implemented\n");
+		DPRINTF(sc->dev,
+		    "ti,index-starts-at-one - Not implemented\n");
 	}
 
 	if (OF_hasprop(node, "ti,set-rate-parent"))
-		device_printf(sc->sc_dev, "ti,set-rate-parent - Not implemented\n");
+		DPRINTF(sc->dev,
+		    "ti,set-rate-parent - Not implemented\n");
 	if (OF_hasprop(node, "ti,latch-bit"))
-		device_printf(sc->sc_dev, "ti,latch-bit - Not implemented\n");
+		DPRINTF(sc->dev,
+		    "ti,latch-bit - Not implemented\n");
 
-	read_clock_cells(sc->sc_dev, &sc->clock_cell);
 
-	create_clkdef(sc->sc_dev, &sc->clock_cell, &sc->mux_def.clkdef);
-
-	/* Figure out the width from ti_max_div */
-	if (sc->mux_def.mux_flags)
-		sc->mux_def.width = fls(sc->clock_cell.num_real_clocks-1);
-	else
-		sc->mux_def.width = fls(sc->clock_cell.num_real_clocks);
-
-	DPRINTF(sc->sc_dev, "sc->clock_cell.num_real_clocks %x def.width %x\n",
-		sc->clock_cell.num_real_clocks, sc->mux_def.width);
-
-	err = find_parent_clock_names(sc->sc_dev, &sc->clock_cell, &sc->mux_def.clkdef);
-
-	if (err) {
-		/* free_clkdef will be called in ti_mux_new_pass */
-		DPRINTF(sc->sc_dev, "find_parent_clock_names failed\n");
-		return (bus_generic_attach(sc->sc_dev));
-	}
-
-	err = register_clk(sc);
-
-	if (err) {
-		/* free_clkdef will be called in ti_mux_new_pass */
-		DPRINTF(sc->sc_dev, "register_clk failed\n");
-		return (bus_generic_attach(sc->sc_dev));
+	/* Find parent in lookup table */
+	for (index = 0; index < nitems(mux_parent_table); index++) {
+		if (strcmp(node_name, mux_parent_table[index].node_name) == 0)
+			break;
 	}
+	if (index == nitems(mux_parent_table))
+		panic("Cant find clock %s\n", node_name);
 
-	sc->attach_done = true;
-
-	free_clkdef(&sc->mux_def.clkdef);
+	DPRINTF(sc->dev, "%s at mux_parent_table[%d]\n",
+			node_name, index);
+	/* Fill clknode_init_def */
+	sc->mux_def.clkdef.id = 1;
+	sc->mux_def.clkdef.flags = CLK_NODE_STATIC_STRINGS;
 
-	return (bus_generic_attach(sc->sc_dev));
-}
+	sc->mux_def.clkdef.name = mux_parent_table[index].node_name;
+	sc->mux_def.clkdef.parent_cnt = mux_parent_table[index].parent_cnt;
+	sc->mux_def.clkdef.parent_names = mux_parent_table[index].parent_names;
 
-static void
-ti_mux_new_pass(device_t dev)
-{
-	struct ti_mux_softc *sc;
-	int err;
+	/* Figure out the width from ti_max_div */
+	if (sc->mux_def.mux_flags)
+		sc->mux_def.width = fls(sc->mux_def.clkdef.parent_cnt-1);
+	else
+		sc->mux_def.width = fls(sc->mux_def.clkdef.parent_cnt);
 
-	sc = device_get_softc(dev);
+	DPRINTF(sc->dev, "parents %x def.width %x\n",
+		sc->mux_def.clkdef.parent_cnt, sc->mux_def.width);
 
-	if (sc->attach_done) {
-		return;
+	sc->clkdom = clkdom_create(sc->dev);
+	if (sc->clkdom == NULL) {
+		DPRINTF(sc->dev, "Failed to create clkdom\n");
+		return ENXIO;
 	}
 
-	err = find_parent_clock_names(sc->sc_dev, &sc->clock_cell, &sc->mux_def.clkdef);
-	if (err) {
-		/* free_clkdef will be called in later call to ti_mux_new_pass */
-		DPRINTF(sc->sc_dev, "ti_mux_new_pass find_parent_clock_names failed\n");
-		return;
+	err = clknode_mux_register(sc->clkdom, &sc->mux_def);
+	if (err != 0) {
+		DPRINTF(sc->dev, "clknode_mux_register failed %x\n", err);
+		return ENXIO;
 	}
 
-	err = register_clk(sc);
-	if (err) {
-		/* free_clkdef will be called in later call to ti_mux_new_pass */
-		DPRINTF(sc->sc_dev, "ti_mux_new_pass register_clk failed\n");
-		return;
+	err = clkdom_finit(sc->clkdom);
+	if (err != 0) {
+		DPRINTF(sc->dev, "Clk domain finit fails %x.\n", err);
+		return ENXIO;
 	}
 
-	sc->attach_done = true;
-
-	free_clkdef(&sc->mux_def.clkdef);
+	return (bus_generic_attach(sc->dev));
 }
 
 static int
@@ -228,8 +271,12 @@
 	DEVMETHOD(device_attach,	ti_mux_attach),
 	DEVMETHOD(device_detach,	ti_mux_detach),
 
-	/* Bus interface */
-	DEVMETHOD(bus_new_pass,		ti_mux_new_pass),
+	/* Clock device interface */
+	DEVMETHOD(clkdev_device_lock,	ti_mux_clkdev_device_lock),
+	DEVMETHOD(clkdev_device_unlock,	ti_mux_clkdev_device_unlock),
+	DEVMETHOD(clkdev_read_4,	ti_mux_clkdev_read_4),
+	DEVMETHOD(clkdev_write_4,	ti_mux_clkdev_write_4),
+	DEVMETHOD(clkdev_modify_4,	ti_mux_clkdev_modify_4),
 
 	DEVMETHOD_END
 };
diff --git a/sys/arm/ti/ti_sysc.c b/sys/arm/ti/ti_sysc.c
--- a/sys/arm/ti/ti_sysc.c
+++ b/sys/arm/ti/ti_sysc.c
@@ -46,9 +46,12 @@
 #include <dev/ofw/ofw_bus_subr.h>
 
 #include <dev/clk/clk.h>
+#include <dev/clk/clk_link.h>
 
 #include <arm/ti/ti_sysc.h>
-#include <arm/ti/clk/clock_common.h>
+#include <arm/ti/clk/am33xx.h>
+#include <arm/ti/clk/ti_clock_common.h>
+#include <arm/ti/ti_cpuid.h>
 
 #define DEBUG_SYSC	0
 
@@ -130,7 +133,6 @@
 
 struct ti_sysc_softc {
 	struct simplebus_softc	sc;
-	bool			attach_done;
 
 	device_t		dev;
 	int			device_type;
@@ -240,7 +242,7 @@
 	TAILQ_FOREACH_SAFE(clkp, &sc->clk_list, next, clkp_tmp) {
 		err = clk_enable(clkp->clk);
 
-		if (err) {
+		if (err != 0) {
 			DPRINTF(sc->dev, "clk_enable %s failed %d\n",
 				clk_get_name(clkp->clk), err);
 			break;
@@ -258,7 +260,7 @@
 	TAILQ_FOREACH_SAFE(clkp, &sc->clk_list, next, clkp_tmp) {
 		err = clk_disable(clkp->clk);
 
-		if (err) {
+		if (err != 0) {
 			DPRINTF(sc->dev, "clk_enable %s failed %d\n",
 				clk_get_name(clkp->clk), err);
 			break;
@@ -277,8 +279,19 @@
 	int err, k, reg_i, prop_idx;
 	uint32_t idx;
 
+	/* Make sure address & size are 0 */
+	for (idx = 0; idx < REG_MAX; idx++) {
+		sc->reg[idx].address = 0;
+		sc->reg[idx].size = 0;
+	}
+
 	node = ofw_bus_get_node(sc->dev);
 
+	/* Ensure its a reg node at all */
+	if (!ofw_bus_has_prop(sc->dev, "reg"))
+		/* Silently ignore for now */
+		return (0);
+
 	/* Get parents address and size properties */
 	err = OF_searchencprop(OF_parent(node), "#address-cells",
 		&parent_address_cells, sizeof(parent_address_cells));
@@ -307,12 +320,6 @@
 	reg = malloc(nreg, M_DEVBUF, M_WAITOK);
 	OF_getencprop(node, "reg", reg, nreg);
 
-	/* Make sure address & size are 0 */
-	for (idx = 0; idx < REG_MAX; idx++) {
-		sc->reg[idx].address = 0;
-		sc->reg[idx].size = 0;
-	}
-
 	/* Loop through reg-names and figure out which reg-name corresponds to
 	 * index populate the values into the reg array.
 	*/
@@ -344,6 +351,7 @@
 			sc->reg[prop_idx].size);
 	}
 	free(reg, M_DEVBUF);
+
 	return (0);
 }
 
@@ -355,9 +363,8 @@
 
 	node = ofw_bus_get_node(sc->dev);
 
-	if (!OF_hasprop(node, name)) {
+	if (OF_hasprop(node, name) == 0)
 		return;
-	}
 
 	len = OF_getproplen(node, name);
 	no = len / sizeof(cell_t);
@@ -393,36 +400,6 @@
 		idle[i] = -1;
 }
 
-static int
-ti_sysc_attach_clocks(struct ti_sysc_softc *sc) {
-	clk_t *clk;
-	struct clk_list *clkp;
-	int index, err;
-
-	clk = malloc(sc->num_clocks*sizeof(clk_t), M_DEVBUF, M_WAITOK | M_ZERO);
-
-	/* Check if all clocks can be found */
-	for (index = 0; index < sc->num_clocks; index++) {
-		err = clk_get_by_ofw_index(sc->dev, 0, index, &clk[index]);
-
-		if (err != 0) {
-			free(clk, M_DEVBUF);
-			return (1);
-		}
-	}
-
-	/* All clocks are found, add to list */
-	for (index = 0; index < sc->num_clocks; index++) {
-		clkp = malloc(sizeof(*clkp), M_DEVBUF, M_WAITOK | M_ZERO);
-		clkp->clk = clk[index];
-		TAILQ_INSERT_TAIL(&sc->clk_list, clkp, next);
-	}
-
-	/* Release the clk array */
-	free(clk, M_DEVBUF);
-	return (0);
-}
-
 static int
 ti_sysc_simplebus_attach_child(device_t dev) {
 	device_t cdev;
@@ -432,6 +409,9 @@
 	node = ofw_bus_get_node(sc->dev);
 
 	for (child = OF_child(node); child > 0; child = OF_peer(child)) {
+		if (!ofw_bus_node_status_okay(child))
+			continue;
+
 		cdev = simplebus_add_device(sc->dev, child, 0, NULL, -1, NULL);
 		if (cdev != NULL)
 			device_probe_and_attach(cdev);
@@ -450,10 +430,73 @@
 		return (ENXIO);
 
 	device_set_desc(dev, "TI SYSC Interconnect");
+	if (bootverbose == 0)
+		device_quiet(dev);
 
 	return (BUS_PROBE_DEFAULT);
 }
 
+static void
+ti_sysc_init_clk_links(device_t dev) {
+	int chip_id;
+	int i, err;
+	struct clkdom *clkdom;
+	device_t child;
+	device_t root_dev = dev;
+	device_t tmp_dev;
+
+	/* find device root to attach the imaginary ti_clkinit.
+	 * Its used to create clk_link for future clocks.
+	 */
+	while (1) {
+		tmp_dev = device_get_parent(root_dev);
+		if (tmp_dev == NULL)
+			break;
+		root_dev = tmp_dev;
+	}
+
+	/* If ti_clkinitX already exist the links are already created */
+	if (device_find_child(root_dev, "ti_clkinit", -1) != NULL) {
+		return;
+	}
+
+	/* otherwise add ti_clkinit as a child to the root */
+	child = device_add_child(root_dev, "ti_clkinit", -1);
+	if (child == NULL)
+		panic("Cant add ti_clkinit\n");
+
+	clkdom = clkdom_create(dev);
+	if (clkdom == NULL)
+		panic("Cannot create clkdom\n");
+
+	chip_id = ti_chip();
+	if (chip_id == CHIP_AM335X) {
+		/*
+		 * pre-create clocks to get handles to parents
+		 * before they actually exists
+		 */
+		for (i = 0; i < nitems(scm_clocks); i++) {
+			err = clknode_link_register(clkdom,
+			    &scm_clocks[i]);
+			if (err != 0)
+				device_printf(dev, "Cant create clock link %s\n",
+				    scm_clocks[i].clkdef.name);
+		}
+		for (i = 0; i < nitems(per_cm_0); i++) {
+			err = clknode_link_register(clkdom,
+			    &per_cm_0[i]);
+			if (err != 0)
+				device_printf(dev, "Cant create clock link %s\n",
+				    per_cm_0[i].clkdef.name);
+		}
+	}
+	else if (chip_id == CHIP_OMAP_4)
+		device_printf(dev, "Todo - add clock support");
+
+	if (clkdom_finit(clkdom) != 0)
+		panic("cannot finalize clkdom initialization\n");
+}
+
 static int
 ti_sysc_attach(device_t dev)
 {
@@ -467,6 +510,9 @@
 	sc->device_type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
 
 	node = ofw_bus_get_node(sc->dev);
+
+	ti_sysc_init_clk_links(dev);
+
 	/* ranges - use simplebus */
 	simplebus_init(sc->dev, node);
 	if (simplebus_fill_ranges(node, &sc->sc) < 0) {
@@ -481,21 +527,21 @@
 
 	/* Required field reg & reg-names - assume at least "rev" exists */
 	err = parse_regfields(sc);
-	if (err) {
+	if (err != 0) {
 		DPRINTF(sc->dev, "parse_regfields failed %d\n", err);
 		return (ENXIO);
 	}
 
 	/* Optional */
-	if (OF_hasprop(node, "ti,sysc-mask")) {
+	if (OF_hasprop(node, "ti,sysc-mask") == 1) {
 		OF_getencprop(node, "ti,sysc-mask", &value, sizeof(cell_t));
 		sc->ti_sysc_mask = value;
 	}
-	if (OF_hasprop(node, "ti,syss-mask")) {
+	if (OF_hasprop(node, "ti,syss-mask") == 1) {
 		OF_getencprop(node, "ti,syss-mask", &value, sizeof(cell_t));
 		sc->ti_syss_mask = value;
 	}
-	if (OF_hasprop(node, "ti,sysc-delay-us")) {
+	if (OF_hasprop(node, "ti,sysc-delay-us") == 1) {
 		OF_getencprop(node, "ti,sysc-delay-us", &value, sizeof(cell_t));
 		sc->ti_sysc_delay_us = value;
 	}
@@ -506,17 +552,17 @@
 	parse_idle(sc, "ti,sysc-midle", sc->ti_sysc_midle);
 	parse_idle(sc, "ti,sysc-sidle", sc->ti_sysc_sidle);
 
-	if (OF_hasprop(node, "ti,no-reset-on-init"))
+	if (OF_hasprop(node, "ti,no-reset-on-init") == 1)
 		sc->ti_no_reset_on_init = true;
 	else
 		sc->ti_no_reset_on_init = false;
 
-	if (OF_hasprop(node, "ti,no-idle-on-init"))
+	if (OF_hasprop(node, "ti,no-idle-on-init") == 1)
 		sc->ti_no_idle_on_init = true;
 	else
 		sc->ti_no_idle_on_init = false;
 
-	if (OF_hasprop(node, "ti,no-idle"))
+	if (OF_hasprop(node, "ti,no-idle") == 1)
 		sc->ti_no_idle = true;
 	else
 		sc->ti_no_idle = false;
@@ -527,31 +573,70 @@
 		sc->ti_no_idle_on_init,
 		sc->ti_no_idle);
 
-	if (OF_hasprop(node, "clocks")) {
-		struct clock_cell_info cell_info;
-		read_clock_cells(sc->dev, &cell_info);
-		free(cell_info.clock_cells, M_DEVBUF);
-		free(cell_info.clock_cells_ncells, M_DEVBUF);
-
-		sc->num_clocks = cell_info.num_real_clocks;
-		TAILQ_INIT(&sc->clk_list);
+	if (OF_hasprop(node, "clocks") == 1) {
+		int idx, clk_idx;
+		const char *name = ofw_bus_get_name(dev);
+		clk_t clkk;
+
+		DPRINTF(dev, "ti_sysc_attach bus name %s\n",
+			name);
+		err = clk_get_by_ofw_index(dev, node, 0, &clkk);
+		if (err == 0) {
+			/* TODO: support multiple clocks.... */
+			struct clk_list *clkp;
+			clkp = malloc(sizeof(*clkp), M_DEVBUF,
+			    M_WAITOK | M_ZERO);
+			err = clk_get_by_ofw_index(dev, node, 0, &clkp->clk);
+
+			DPRINTF(dev, "err %d clk_get_name: %s\n",
+				err, clk_get_name(clkk));
+			TAILQ_INIT(&sc->clk_list);
+			sc->num_clocks =  1; //sysc_clock_table[idx].parent_cnt;
+			TAILQ_INSERT_TAIL(&sc->clk_list, clkp, next);
+		} else {
+			DPRINTF(dev, "USE LOOKUP TABLE\n");
+			for (idx = 0; idx < nitems(sysc_clock_table); idx++) {
+				if (strcmp(sysc_clock_table[idx].node_name, name)==0)
+					break;
+			}
 
-		err = ti_sysc_attach_clocks(sc);
-		if (err) {
-			DPRINTF(sc->dev, "Failed to attach clocks\n");
-			return (bus_generic_attach(sc->dev));
-		}
+			if (idx == nitems(sysc_clock_table))
+				panic("Cant find clocks for node %s\n", name);
+
+			DPRINTF(dev, "%s at sysc_clock_table[%d]\n", name, idx);
+			/*
+			 * Found the correct place in the lookup table.
+			 * Loop through and get the clocks
+			 */
+
+			TAILQ_INIT(&sc->clk_list);
+			sc->num_clocks = sysc_clock_table[idx].parent_cnt;
+			clk_idx = 0;
+			for (; clk_idx < sysc_clock_table[idx].parent_cnt; clk_idx++) {
+				struct clk_list *clkp;
+				clkp = malloc(sizeof(*clkp), M_DEVBUF,
+				    M_WAITOK | M_ZERO);
+
+				err = clk_get_by_name(dev,
+				    sysc_clock_table[idx].parent_names[clk_idx],
+				    &clkp->clk);
+				if (err != 0)
+					panic("Cant get clock %s err %d",
+					  sysc_clock_table[idx].parent_names[clk_idx],
+					  err);
+
+				TAILQ_INSERT_TAIL(&sc->clk_list, clkp, next);
+			} /* for */
+		} /* else */
 	}
 
 	err = ti_sysc_simplebus_attach_child(sc->dev);
-	if (err) {
+	if (err != 0) {
 		DPRINTF(sc->dev, "ti_sysc_simplebus_attach_child %d\n",
 		    err);
 		return (err);
 	}
 
-	sc->attach_done = true;
-
 	return (bus_generic_attach(sc->dev));
 }
 
@@ -561,50 +646,12 @@
 	return (EBUSY);
 }
 
-/* Bus interface */
-static void
-ti_sysc_new_pass(device_t dev)
-{
-	struct ti_sysc_softc *sc;
-	int err;
-	phandle_t node;
-
-	sc = device_get_softc(dev);
-
-	if (sc->attach_done) {
-		bus_generic_new_pass(sc->dev);
-		return;
-	}
-
-	node = ofw_bus_get_node(sc->dev);
-	if (OF_hasprop(node, "clocks")) {
-		err = ti_sysc_attach_clocks(sc);
-		if (err) {
-			DPRINTF(sc->dev, "Failed to attach clocks\n");
-			return;
-		}
-	}
-
-	err = ti_sysc_simplebus_attach_child(sc->dev);
-	if (err) {
-		DPRINTF(sc->dev,
-		    "ti_sysc_simplebus_attach_child failed %d\n", err);
-		return;
-	}
-	sc->attach_done = true;
-
-	bus_generic_attach(sc->dev);
-}
-
 static device_method_t ti_sysc_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		ti_sysc_probe),
 	DEVMETHOD(device_attach,	ti_sysc_attach),
 	DEVMETHOD(device_detach,	ti_sysc_detach),
 
-	/* Bus interface */
-	DEVMETHOD(bus_new_pass,		ti_sysc_new_pass),
-
 	DEVMETHOD_END
 };
 
@@ -612,4 +659,4 @@
 	sizeof(struct ti_sysc_softc), simplebus_driver);
 
 EARLY_DRIVER_MODULE(ti_sysc, simplebus, ti_sysc_driver, 0, 0,
-    BUS_PASS_BUS + BUS_PASS_ORDER_FIRST);
+    BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);