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 + * + * 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 +#include +#include + +/* === 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 #include +#include #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 #include +#include +#include +#include #include #include #include +#include +#include #include #include #include +#include #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, ÷r); + 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 + * + * 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 +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 #include #include @@ -37,10 +42,15 @@ #include #include +#include #include #include -#include "clock_common.h" +#include +#include +#include +#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 #include #include @@ -40,8 +45,9 @@ #include #include +#include #include -#include "clock_common.h" +#include #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 #include #include @@ -36,11 +41,16 @@ #include #include -#include #include #include +#include +#include -#include "clock_common.h" +#include +#include +#include +#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 #include #include @@ -39,10 +44,16 @@ #include #include +#include + #include #include -#include "clock_common.h" +#include +#include +#include +#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 #include +#include #include -#include +#include +#include +#include #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);