···11-NVIDIA Tegra124 Clock And Reset Controller11+NVIDIA Tegra124 and Tegra132 Clock And Reset Controller2233This binding uses the common clock binding:44Documentation/devicetree/bindings/clock/clock-bindings.txt···77for muxing and gating Tegra's clocks, and setting their rates.8899Required properties :1010-- compatible : Should be "nvidia,tegra124-car"1010+- compatible : Should be "nvidia,tegra124-car" or "nvidia,tegra132-car"1111- reg : Should contain CAR registers location and length1212- clocks : Should contain phandle and clock specifiers for two clocks:1313 the 32 KHz "32k_in", and the board-specific oscillator "osc".1414- #clock-cells : Should be 1.1515 In clock consumers, this cell represents the clock ID exposed by the1616- CAR. The assignments may be found in header file1717- <dt-bindings/clock/tegra124-car.h>.1616+ CAR. The assignments may be found in the header files1717+ <dt-bindings/clock/tegra124-car-common.h> (which covers IDs common1818+ to Tegra124 and Tegra132) and <dt-bindings/clock/tegra124-car.h>1919+ (for Tegra124-specific clocks).1820- #reset-cells : Should be 1.1921 In clock consumers, this cell represents the bit number in the CAR's2022 array of CLK_RST_CONTROLLER_RST_DEVICES_* registers.
···11/*22- * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved.22+ * Copyright (c) 2012-2014 NVIDIA CORPORATION. All rights reserved.33 *44 * This program is free software; you can redistribute it and/or modify it55 * under the terms and conditions of the GNU General Public License,···27272828#include "clk.h"2929#include "clk-id.h"3030+3131+/*3232+ * TEGRA124_CAR_BANK_COUNT: the number of peripheral clock register3333+ * banks present in the Tegra124/132 CAR IP block. The banks are3434+ * identified by single letters, e.g.: L, H, U, V, W, X. See3535+ * periph_regs[] in drivers/clk/tegra/clk.c3636+ */3737+#define TEGRA124_CAR_BANK_COUNT 630383139#define CLK_SOURCE_CSITE 0x1d43240#define CLK_SOURCE_EMC 0x19c···136128static unsigned long pll_ref_freq;137129138130static DEFINE_SPINLOCK(pll_d_lock);139139-static DEFINE_SPINLOCK(pll_d2_lock);140131static DEFINE_SPINLOCK(pll_e_lock);141132static DEFINE_SPINLOCK(pll_re_lock);142133static DEFINE_SPINLOCK(pll_u_lock);···151144 [9] = 48000000,152145 [12] = 260000000,153146};154154-155155-static const char *mux_plld_out0_plld2_out0[] = {156156- "pll_d_out0", "pll_d2_out0",157157-};158158-#define mux_plld_out0_plld2_out0_idx NULL159147160148static const char *mux_pllmcp_clkm[] = {161149 "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_c2", "pll_c3",···785783 [tegra_clk_sbc2] = { .dt_id = TEGRA124_CLK_SBC2, .present = true },786784 [tegra_clk_sbc3] = { .dt_id = TEGRA124_CLK_SBC3, .present = true },787785 [tegra_clk_i2c5] = { .dt_id = TEGRA124_CLK_I2C5, .present = true },788788- [tegra_clk_dsia] = { .dt_id = TEGRA124_CLK_DSIA, .present = true },789786 [tegra_clk_mipi] = { .dt_id = TEGRA124_CLK_MIPI, .present = true },790787 [tegra_clk_hdmi] = { .dt_id = TEGRA124_CLK_HDMI, .present = true },791788 [tegra_clk_csi] = { .dt_id = TEGRA124_CLK_CSI, .present = true },···810809 [tegra_clk_soc_therm] = { .dt_id = TEGRA124_CLK_SOC_THERM, .present = true },811810 [tegra_clk_dtv] = { .dt_id = TEGRA124_CLK_DTV, .present = true },812811 [tegra_clk_i2cslow] = { .dt_id = TEGRA124_CLK_I2CSLOW, .present = true },813813- [tegra_clk_dsib] = { .dt_id = TEGRA124_CLK_DSIB, .present = true },814812 [tegra_clk_tsec] = { .dt_id = TEGRA124_CLK_TSEC, .present = true },815813 [tegra_clk_xusb_host] = { .dt_id = TEGRA124_CLK_XUSB_HOST, .present = true },816814 [tegra_clk_msenc] = { .dt_id = TEGRA124_CLK_MSENC, .present = true },···949949 [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_1_MUX, .present = true },950950 [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_2_MUX, .present = true },951951 [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_3_MUX, .present = true },952952- [tegra_clk_dsia_mux] = { .dt_id = TEGRA124_CLK_DSIA_MUX, .present = true },953953- [tegra_clk_dsib_mux] = { .dt_id = TEGRA124_CLK_DSIB_MUX, .present = true },954952};955953956954static struct tegra_devclk devclks[] __initdata = {···11101112 1, 2);11111113 clks[TEGRA124_CLK_XUSB_SS_DIV2] = clk;1112111411131113- /* dsia mux */11141114- clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0,11151115- ARRAY_SIZE(mux_plld_out0_plld2_out0), 0,11161116- clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock);11171117- clks[TEGRA124_CLK_DSIA_MUX] = clk;11151115+ clk = clk_register_gate(NULL, "plld_dsi", "plld_out0", 0,11161116+ clk_base + PLLD_MISC, 30, 0, &pll_d_lock);11171117+ clks[TEGRA124_CLK_PLLD_DSI] = clk;1118111811191119- /* dsib mux */11201120- clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0,11211121- ARRAY_SIZE(mux_plld_out0_plld2_out0), 0,11221122- clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock);11231123- clks[TEGRA124_CLK_DSIB_MUX] = clk;11191119+ clk = tegra_clk_register_periph_gate("dsia", "plld_dsi", 0, clk_base,11201120+ 0, 48, periph_clk_enb_refcnt);11211121+ clks[TEGRA124_CLK_DSIA] = clk;11221122+11231123+ clk = tegra_clk_register_periph_gate("dsib", "plld_dsi", 0, clk_base,11241124+ 0, 82, periph_clk_enb_refcnt);11251125+ clks[TEGRA124_CLK_DSIB] = clk;1124112611251127 /* emc mux */11261128 clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,···13491351 {},13501352};1351135313521352-static struct tegra_clk_init_table init_table[] __initdata = {13541354+static struct tegra_clk_init_table common_init_table[] __initdata = {13531355 {TEGRA124_CLK_UARTA, TEGRA124_CLK_PLL_P, 408000000, 0},13541356 {TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 408000000, 0},13551357 {TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 408000000, 0},···13661368 {TEGRA124_CLK_I2S4, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0},13671369 {TEGRA124_CLK_VDE, TEGRA124_CLK_PLL_P, 0, 0},13681370 {TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1},13711371+ {TEGRA124_CLK_DSIALP, TEGRA124_CLK_PLL_P, 68000000, 0},13721372+ {TEGRA124_CLK_DSIBLP, TEGRA124_CLK_PLL_P, 68000000, 0},13691373 {TEGRA124_CLK_SCLK, TEGRA124_CLK_PLL_P_OUT2, 102000000, 1},13701374 {TEGRA124_CLK_DFLL_SOC, TEGRA124_CLK_PLL_P, 51000000, 1},13711375 {TEGRA124_CLK_DFLL_REF, TEGRA124_CLK_PLL_P, 51000000, 1},···13851385 {TEGRA124_CLK_SATA, TEGRA124_CLK_PLL_P, 104000000, 0},13861386 {TEGRA124_CLK_SATA_OOB, TEGRA124_CLK_PLL_P, 204000000, 0},13871387 {TEGRA124_CLK_EMC, TEGRA124_CLK_CLK_MAX, 0, 1},13881388- {TEGRA124_CLK_CCLK_G, TEGRA124_CLK_CLK_MAX, 0, 1},13891388 {TEGRA124_CLK_MSELECT, TEGRA124_CLK_CLK_MAX, 0, 1},13901389 {TEGRA124_CLK_CSITE, TEGRA124_CLK_CLK_MAX, 0, 1},13911390 {TEGRA124_CLK_TSENSOR, TEGRA124_CLK_CLK_M, 400000, 0},13921392- {TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 0},13931391 /* This MUST be the last entry. */13941392 {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},13951393};1396139413951395+static struct tegra_clk_init_table tegra124_init_table[] __initdata = {13961396+ {TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 0},13971397+ {TEGRA124_CLK_CCLK_G, TEGRA124_CLK_CLK_MAX, 0, 1},13981398+ /* This MUST be the last entry. */13991399+ {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},14001400+};14011401+14021402+/* Tegra132 requires the SOC_THERM clock to remain active */14031403+static struct tegra_clk_init_table tegra132_init_table[] __initdata = {14041404+ {TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 1},14051405+ /* This MUST be the last entry. */14061406+ {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},14071407+};14081408+14091409+/**14101410+ * tegra124_clock_apply_init_table - initialize clocks on Tegra124 SoCs14111411+ *14121412+ * Program an initial clock rate and enable or disable clocks needed14131413+ * by the rest of the kernel, for Tegra124 SoCs. It is intended to be14141414+ * called by assigning a pointer to it to tegra_clk_apply_init_table -14151415+ * this will be called as an arch_initcall. No return value.14161416+ */13971417static void __init tegra124_clock_apply_init_table(void)13981418{13991399- tegra_init_from_table(init_table, clks, TEGRA124_CLK_CLK_MAX);14191419+ tegra_init_from_table(common_init_table, clks, TEGRA124_CLK_CLK_MAX);14201420+ tegra_init_from_table(tegra124_init_table, clks, TEGRA124_CLK_CLK_MAX);14001421}1401142214021402-static void __init tegra124_clock_init(struct device_node *np)14231423+/**14241424+ * tegra132_clock_apply_init_table - initialize clocks on Tegra132 SoCs14251425+ *14261426+ * Program an initial clock rate and enable or disable clocks needed14271427+ * by the rest of the kernel, for Tegra132 SoCs. It is intended to be14281428+ * called by assigning a pointer to it to tegra_clk_apply_init_table -14291429+ * this will be called as an arch_initcall. No return value.14301430+ */14311431+static void __init tegra132_clock_apply_init_table(void)14321432+{14331433+ tegra_init_from_table(common_init_table, clks, TEGRA124_CLK_CLK_MAX);14341434+ tegra_init_from_table(tegra132_init_table, clks, TEGRA124_CLK_CLK_MAX);14351435+}14361436+14371437+/**14381438+ * tegra124_132_clock_init_pre - clock initialization preamble for T124/T13214391439+ * @np: struct device_node * of the DT node for the SoC CAR IP block14401440+ *14411441+ * Register most of the clocks controlled by the CAR IP block, along14421442+ * with a few clocks controlled by the PMC IP block. Everything in14431443+ * this function should be common to Tegra124 and Tegra132. XXX The14441444+ * PMC clock initialization should probably be moved to PMC-specific14451445+ * driver code. No return value.14461446+ */14471447+static void __init tegra124_132_clock_init_pre(struct device_node *np)14031448{14041449 struct device_node *node;14501450+ u32 plld_base;1405145114061452 clk_base = of_iomap(np, 0);14071453 if (!clk_base) {14081408- pr_err("ioremap tegra124 CAR failed\n");14541454+ pr_err("ioremap tegra124/tegra132 CAR failed\n");14091455 return;14101456 }14111457···14691423 return;14701424 }1471142514721472- clks = tegra_clk_init(clk_base, TEGRA124_CLK_CLK_MAX, 6);14261426+ clks = tegra_clk_init(clk_base, TEGRA124_CLK_CLK_MAX,14271427+ TEGRA124_CAR_BANK_COUNT);14731428 if (!clks)14741429 return;14751430···14841437 tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks, &pll_a_params);14851438 tegra_pmc_clk_init(pmc_base, tegra124_clks);1486143914401440+ /* For Tegra124 & Tegra132, PLLD is the only source for DSIA & DSIB */14411441+ plld_base = clk_readl(clk_base + PLLD_BASE);14421442+ plld_base &= ~BIT(25);14431443+ clk_writel(plld_base, clk_base + PLLD_BASE);14441444+}14451445+14461446+/**14471447+ * tegra124_132_clock_init_post - clock initialization postamble for T124/T13214481448+ * @np: struct device_node * of the DT node for the SoC CAR IP block14491449+ *14501450+ * Register most of the along with a few clocks controlled by the PMC14511451+ * IP block. Everything in this function should be common to Tegra12414521452+ * and Tegra132. This function must be called after14531453+ * tegra124_132_clock_init_pre(), otherwise clk_base and pmc_base will14541454+ * not be set. No return value.14551455+ */14561456+static void __init tegra124_132_clock_init_post(struct device_node *np)14571457+{14871458 tegra_super_clk_gen4_init(clk_base, pmc_base, tegra124_clks,14881488- &pll_x_params);14591459+ &pll_x_params);14891460 tegra_add_of_provider(np);14901461 tegra_register_devclks(devclks, ARRAY_SIZE(devclks));1491146214921492- tegra_clk_apply_init_table = tegra124_clock_apply_init_table;14931493-14941463 tegra_cpu_car_ops = &tegra124_cpu_car_ops;14951464}14651465+14661466+/**14671467+ * tegra124_clock_init - Tegra124-specific clock initialization14681468+ * @np: struct device_node * of the DT node for the SoC CAR IP block14691469+ *14701470+ * Register most SoC clocks for the Tegra124 system-on-chip. Most of14711471+ * this code is shared between the Tegra124 and Tegra132 SoCs,14721472+ * although some of the initial clock settings and CPU clocks differ.14731473+ * Intended to be called by the OF init code when a DT node with the14741474+ * "nvidia,tegra124-car" string is encountered, and declared with14751475+ * CLK_OF_DECLARE. No return value.14761476+ */14771477+static void __init tegra124_clock_init(struct device_node *np)14781478+{14791479+ tegra124_132_clock_init_pre(np);14801480+ tegra_clk_apply_init_table = tegra124_clock_apply_init_table;14811481+ tegra124_132_clock_init_post(np);14821482+}14831483+14841484+/**14851485+ * tegra132_clock_init - Tegra132-specific clock initialization14861486+ * @np: struct device_node * of the DT node for the SoC CAR IP block14871487+ *14881488+ * Register most SoC clocks for the Tegra132 system-on-chip. Most of14891489+ * this code is shared between the Tegra124 and Tegra132 SoCs,14901490+ * although some of the initial clock settings and CPU clocks differ.14911491+ * Intended to be called by the OF init code when a DT node with the14921492+ * "nvidia,tegra132-car" string is encountered, and declared with14931493+ * CLK_OF_DECLARE. No return value.14941494+ */14951495+static void __init tegra132_clock_init(struct device_node *np)14961496+{14971497+ tegra124_132_clock_init_pre(np);14981498+14991499+ /*15001500+ * On Tegra132, these clocks are controlled by the15011501+ * CLUSTER_clocks IP block, located in the CPU complex15021502+ */15031503+ tegra124_clks[tegra_clk_cclk_g].present = false;15041504+ tegra124_clks[tegra_clk_cclk_lp].present = false;15051505+ tegra124_clks[tegra_clk_pll_x].present = false;15061506+ tegra124_clks[tegra_clk_pll_x_out0].present = false;15071507+15081508+ tegra_clk_apply_init_table = tegra132_clock_apply_init_table;15091509+ tegra124_132_clock_init_post(np);15101510+}14961511CLK_OF_DECLARE(tegra124, "nvidia,tegra124-car", tegra124_clock_init);15121512+CLK_OF_DECLARE(tegra132, "nvidia,tegra132-car", tegra132_clock_init);
+5-2
drivers/clk/tegra/clk.c
···302302303303tegra_clk_apply_init_table_func tegra_clk_apply_init_table;304304305305-void __init tegra_clocks_apply_init_table(void)305305+static int __init tegra_clocks_apply_init_table(void)306306{307307 if (!tegra_clk_apply_init_table)308308- return;308308+ return 0;309309310310 tegra_clk_apply_init_table();311311+312312+ return 0;311313}314314+arch_initcall(tegra_clocks_apply_init_table);