1 /* 2 * AM33XX Clock init 3 * 4 * Copyright (C) 2013 Texas Instruments, Inc 5 * Tero Kristo (t-kristo@ti.com) 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation version 2. 10 * 11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 12 * kind, whether express or implied; without even the implied warranty 13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16 17 #include <linux/kernel.h> 18 #include <linux/list.h> 19 #include <linux/clk.h> 20 #include <linux/clk-provider.h> 21 #include <linux/clk/ti.h> 22 #include <dt-bindings/clock/am3.h> 23 24 #include "clock.h" 25 26 static const char *enable_init_clks[] = { 27 "dpll_ddr_m2_ck", 28 "dpll_mpu_m2_ck", 29 "l3_gclk", 30 "l4hs_gclk", 31 "l4fw_gclk", 32 "l4ls_gclk", 33 /* Required for external peripherals like, Audio codecs */ 34 "clkout2_ck", 35 }; 36 37 int __init am33xx_dt_clk_init(void) 38 { 39 struct clk *clk1, *clk2; 40 41 ti_dt_clocks_register(am33xx_compat_clks); 42 43 omap2_clk_disable_autoidle_all(); 44 45 ti_clk_add_aliases(); 46 47 omap2_clk_enable_init_clocks(enable_init_clks, 48 ARRAY_SIZE(enable_init_clks)); 49 50 /* TRM ERRATA: Timer 3 & 6 default parent (TCLKIN) may not be always 51 * physically present, in such a case HWMOD enabling of 52 * clock would be failure with default parent. And timer 53 * probe thinks clock is already enabled, this leads to 54 * crash upon accessing timer 3 & 6 registers in probe. 55 * Fix by setting parent of both these timers to master 56 * oscillator clock. 57 */ 58 59 clk1 = clk_get_sys(NULL, "sys_clkin_ck"); 60 clk2 = clk_get_sys(NULL, "timer3_fck"); 61 clk_set_parent(clk2, clk1); 62 63 clk2 = clk_get_sys(NULL, "timer6_fck"); 64 clk_set_parent(clk2, clk1); 65 /* 66 * The On-Chip 32K RC Osc clock is not an accurate clock-source as per 67 * the design/spec, so as a result, for example, timer which supposed 68 * to get expired @60Sec, but will expire somewhere ~@40Sec, which is 69 * not expected by any use-case, so change WDT1 clock source to PRCM 70 * 32KHz clock. 71 */ 72 clk1 = clk_get_sys(NULL, "wdt1_fck"); 73 clk2 = clk_get_sys(NULL, "clkdiv32k_ick"); 74 clk_set_parent(clk1, clk2); 75 76 return 0; 77 } 78