18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/arch/arm/mach-omap1/clock.h 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2004 - 2005, 2009 Nokia corporation 68c2ecf20Sopenharmony_ci * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> 78c2ecf20Sopenharmony_ci * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#ifndef __ARCH_ARM_MACH_OMAP1_CLOCK_H 118c2ecf20Sopenharmony_ci#define __ARCH_ARM_MACH_OMAP1_CLOCK_H 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/clk.h> 148c2ecf20Sopenharmony_ci#include <linux/list.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include <linux/clkdev.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_cistruct module; 198c2ecf20Sopenharmony_cistruct clk; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cistruct omap_clk { 228c2ecf20Sopenharmony_ci u16 cpu; 238c2ecf20Sopenharmony_ci struct clk_lookup lk; 248c2ecf20Sopenharmony_ci}; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#define CLK(dev, con, ck, cp) \ 278c2ecf20Sopenharmony_ci { \ 288c2ecf20Sopenharmony_ci .cpu = cp, \ 298c2ecf20Sopenharmony_ci .lk = { \ 308c2ecf20Sopenharmony_ci .dev_id = dev, \ 318c2ecf20Sopenharmony_ci .con_id = con, \ 328c2ecf20Sopenharmony_ci .clk = ck, \ 338c2ecf20Sopenharmony_ci }, \ 348c2ecf20Sopenharmony_ci } 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci/* Platform flags for the clkdev-OMAP integration code */ 378c2ecf20Sopenharmony_ci#define CK_310 (1 << 0) 388c2ecf20Sopenharmony_ci#define CK_7XX (1 << 1) /* 7xx, 850 */ 398c2ecf20Sopenharmony_ci#define CK_1510 (1 << 2) 408c2ecf20Sopenharmony_ci#define CK_16XX (1 << 3) /* 16xx, 17xx, 5912 */ 418c2ecf20Sopenharmony_ci#define CK_1710 (1 << 4) /* 1710 extra for rate selection */ 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci/* Temporary, needed during the common clock framework conversion */ 458c2ecf20Sopenharmony_ci#define __clk_get_name(clk) (clk->name) 468c2ecf20Sopenharmony_ci#define __clk_get_parent(clk) (clk->parent) 478c2ecf20Sopenharmony_ci#define __clk_get_rate(clk) (clk->rate) 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci/** 508c2ecf20Sopenharmony_ci * struct clkops - some clock function pointers 518c2ecf20Sopenharmony_ci * @enable: fn ptr that enables the current clock in hardware 528c2ecf20Sopenharmony_ci * @disable: fn ptr that enables the current clock in hardware 538c2ecf20Sopenharmony_ci * @find_idlest: function returning the IDLEST register for the clock's IP blk 548c2ecf20Sopenharmony_ci * @find_companion: function returning the "companion" clk reg for the clock 558c2ecf20Sopenharmony_ci * @allow_idle: fn ptr that enables autoidle for the current clock in hardware 568c2ecf20Sopenharmony_ci * @deny_idle: fn ptr that disables autoidle for the current clock in hardware 578c2ecf20Sopenharmony_ci * 588c2ecf20Sopenharmony_ci * A "companion" clk is an accompanying clock to the one being queried 598c2ecf20Sopenharmony_ci * that must be enabled for the IP module connected to the clock to 608c2ecf20Sopenharmony_ci * become accessible by the hardware. Neither @find_idlest nor 618c2ecf20Sopenharmony_ci * @find_companion should be needed; that information is IP 628c2ecf20Sopenharmony_ci * block-specific; the hwmod code has been created to handle this, but 638c2ecf20Sopenharmony_ci * until hwmod data is ready and drivers have been converted to use PM 648c2ecf20Sopenharmony_ci * runtime calls in place of clk_enable()/clk_disable(), @find_idlest and 658c2ecf20Sopenharmony_ci * @find_companion must, unfortunately, remain. 668c2ecf20Sopenharmony_ci */ 678c2ecf20Sopenharmony_cistruct clkops { 688c2ecf20Sopenharmony_ci int (*enable)(struct clk *); 698c2ecf20Sopenharmony_ci void (*disable)(struct clk *); 708c2ecf20Sopenharmony_ci void (*find_idlest)(struct clk *, void __iomem **, 718c2ecf20Sopenharmony_ci u8 *, u8 *); 728c2ecf20Sopenharmony_ci void (*find_companion)(struct clk *, void __iomem **, 738c2ecf20Sopenharmony_ci u8 *); 748c2ecf20Sopenharmony_ci void (*allow_idle)(struct clk *); 758c2ecf20Sopenharmony_ci void (*deny_idle)(struct clk *); 768c2ecf20Sopenharmony_ci}; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci/* 798c2ecf20Sopenharmony_ci * struct clk.flags possibilities 808c2ecf20Sopenharmony_ci * 818c2ecf20Sopenharmony_ci * XXX document the rest of the clock flags here 828c2ecf20Sopenharmony_ci * 838c2ecf20Sopenharmony_ci * CLOCK_CLKOUTX2: (OMAP4 only) DPLL CLKOUT and CLKOUTX2 GATE_CTRL 848c2ecf20Sopenharmony_ci * bits share the same register. This flag allows the 858c2ecf20Sopenharmony_ci * omap4_dpllmx*() code to determine which GATE_CTRL bit field 868c2ecf20Sopenharmony_ci * should be used. This is a temporary solution - a better approach 878c2ecf20Sopenharmony_ci * would be to associate clock type-specific data with the clock, 888c2ecf20Sopenharmony_ci * similar to the struct dpll_data approach. 898c2ecf20Sopenharmony_ci */ 908c2ecf20Sopenharmony_ci#define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */ 918c2ecf20Sopenharmony_ci#define CLOCK_IDLE_CONTROL (1 << 1) 928c2ecf20Sopenharmony_ci#define CLOCK_NO_IDLE_PARENT (1 << 2) 938c2ecf20Sopenharmony_ci#define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */ 948c2ecf20Sopenharmony_ci#define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */ 958c2ecf20Sopenharmony_ci#define CLOCK_CLKOUTX2 (1 << 5) 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci/** 988c2ecf20Sopenharmony_ci * struct clk - OMAP struct clk 998c2ecf20Sopenharmony_ci * @node: list_head connecting this clock into the full clock list 1008c2ecf20Sopenharmony_ci * @ops: struct clkops * for this clock 1018c2ecf20Sopenharmony_ci * @name: the name of the clock in the hardware (used in hwmod data and debug) 1028c2ecf20Sopenharmony_ci * @parent: pointer to this clock's parent struct clk 1038c2ecf20Sopenharmony_ci * @children: list_head connecting to the child clks' @sibling list_heads 1048c2ecf20Sopenharmony_ci * @sibling: list_head connecting this clk to its parent clk's @children 1058c2ecf20Sopenharmony_ci * @rate: current clock rate 1068c2ecf20Sopenharmony_ci * @enable_reg: register to write to enable the clock (see @enable_bit) 1078c2ecf20Sopenharmony_ci * @recalc: fn ptr that returns the clock's current rate 1088c2ecf20Sopenharmony_ci * @set_rate: fn ptr that can change the clock's current rate 1098c2ecf20Sopenharmony_ci * @round_rate: fn ptr that can round the clock's current rate 1108c2ecf20Sopenharmony_ci * @init: fn ptr to do clock-specific initialization 1118c2ecf20Sopenharmony_ci * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg) 1128c2ecf20Sopenharmony_ci * @usecount: number of users that have requested this clock to be enabled 1138c2ecf20Sopenharmony_ci * @fixed_div: when > 0, this clock's rate is its parent's rate / @fixed_div 1148c2ecf20Sopenharmony_ci * @flags: see "struct clk.flags possibilities" above 1158c2ecf20Sopenharmony_ci * @rate_offset: bitshift for rate selection bitfield (OMAP1 only) 1168c2ecf20Sopenharmony_ci * @src_offset: bitshift for source selection bitfield (OMAP1 only) 1178c2ecf20Sopenharmony_ci * 1188c2ecf20Sopenharmony_ci * XXX @rate_offset, @src_offset should probably be removed and OMAP1 1198c2ecf20Sopenharmony_ci * clock code converted to use clksel. 1208c2ecf20Sopenharmony_ci * 1218c2ecf20Sopenharmony_ci * XXX @usecount is poorly named. It should be "enable_count" or 1228c2ecf20Sopenharmony_ci * something similar. "users" in the description refers to kernel 1238c2ecf20Sopenharmony_ci * code (core code or drivers) that have called clk_enable() and not 1248c2ecf20Sopenharmony_ci * yet called clk_disable(); the usecount of parent clocks is also 1258c2ecf20Sopenharmony_ci * incremented by the clock code when clk_enable() is called on child 1268c2ecf20Sopenharmony_ci * clocks and decremented by the clock code when clk_disable() is 1278c2ecf20Sopenharmony_ci * called on child clocks. 1288c2ecf20Sopenharmony_ci * 1298c2ecf20Sopenharmony_ci * XXX @clkdm, @usecount, @children, @sibling should be marked for 1308c2ecf20Sopenharmony_ci * internal use only. 1318c2ecf20Sopenharmony_ci * 1328c2ecf20Sopenharmony_ci * @children and @sibling are used to optimize parent-to-child clock 1338c2ecf20Sopenharmony_ci * tree traversals. (child-to-parent traversals use @parent.) 1348c2ecf20Sopenharmony_ci * 1358c2ecf20Sopenharmony_ci * XXX The notion of the clock's current rate probably needs to be 1368c2ecf20Sopenharmony_ci * separated from the clock's target rate. 1378c2ecf20Sopenharmony_ci */ 1388c2ecf20Sopenharmony_cistruct clk { 1398c2ecf20Sopenharmony_ci struct list_head node; 1408c2ecf20Sopenharmony_ci const struct clkops *ops; 1418c2ecf20Sopenharmony_ci const char *name; 1428c2ecf20Sopenharmony_ci struct clk *parent; 1438c2ecf20Sopenharmony_ci struct list_head children; 1448c2ecf20Sopenharmony_ci struct list_head sibling; /* node for children */ 1458c2ecf20Sopenharmony_ci unsigned long rate; 1468c2ecf20Sopenharmony_ci void __iomem *enable_reg; 1478c2ecf20Sopenharmony_ci unsigned long (*recalc)(struct clk *); 1488c2ecf20Sopenharmony_ci int (*set_rate)(struct clk *, unsigned long); 1498c2ecf20Sopenharmony_ci long (*round_rate)(struct clk *, unsigned long); 1508c2ecf20Sopenharmony_ci void (*init)(struct clk *); 1518c2ecf20Sopenharmony_ci u8 enable_bit; 1528c2ecf20Sopenharmony_ci s8 usecount; 1538c2ecf20Sopenharmony_ci u8 fixed_div; 1548c2ecf20Sopenharmony_ci u8 flags; 1558c2ecf20Sopenharmony_ci u8 rate_offset; 1568c2ecf20Sopenharmony_ci u8 src_offset; 1578c2ecf20Sopenharmony_ci#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) 1588c2ecf20Sopenharmony_ci struct dentry *dent; /* For visible tree hierarchy */ 1598c2ecf20Sopenharmony_ci#endif 1608c2ecf20Sopenharmony_ci}; 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_cistruct clk_functions { 1638c2ecf20Sopenharmony_ci int (*clk_enable)(struct clk *clk); 1648c2ecf20Sopenharmony_ci void (*clk_disable)(struct clk *clk); 1658c2ecf20Sopenharmony_ci long (*clk_round_rate)(struct clk *clk, unsigned long rate); 1668c2ecf20Sopenharmony_ci int (*clk_set_rate)(struct clk *clk, unsigned long rate); 1678c2ecf20Sopenharmony_ci int (*clk_set_parent)(struct clk *clk, struct clk *parent); 1688c2ecf20Sopenharmony_ci void (*clk_allow_idle)(struct clk *clk); 1698c2ecf20Sopenharmony_ci void (*clk_deny_idle)(struct clk *clk); 1708c2ecf20Sopenharmony_ci void (*clk_disable_unused)(struct clk *clk); 1718c2ecf20Sopenharmony_ci}; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ciextern int clk_init(struct clk_functions *custom_clocks); 1748c2ecf20Sopenharmony_ciextern void clk_preinit(struct clk *clk); 1758c2ecf20Sopenharmony_ciextern int clk_register(struct clk *clk); 1768c2ecf20Sopenharmony_ciextern void clk_reparent(struct clk *child, struct clk *parent); 1778c2ecf20Sopenharmony_ciextern void clk_unregister(struct clk *clk); 1788c2ecf20Sopenharmony_ciextern void propagate_rate(struct clk *clk); 1798c2ecf20Sopenharmony_ciextern void recalculate_root_clocks(void); 1808c2ecf20Sopenharmony_ciextern unsigned long followparent_recalc(struct clk *clk); 1818c2ecf20Sopenharmony_ciextern void clk_enable_init_clocks(void); 1828c2ecf20Sopenharmony_ciunsigned long omap_fixed_divisor_recalc(struct clk *clk); 1838c2ecf20Sopenharmony_ciextern struct clk *omap_clk_get_by_name(const char *name); 1848c2ecf20Sopenharmony_ciextern int omap_clk_enable_autoidle_all(void); 1858c2ecf20Sopenharmony_ciextern int omap_clk_disable_autoidle_all(void); 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ciextern const struct clkops clkops_null; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ciextern struct clk dummy_ck; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ciint omap1_clk_init(void); 1928c2ecf20Sopenharmony_civoid omap1_clk_late_init(void); 1938c2ecf20Sopenharmony_ciextern int omap1_clk_enable(struct clk *clk); 1948c2ecf20Sopenharmony_ciextern void omap1_clk_disable(struct clk *clk); 1958c2ecf20Sopenharmony_ciextern long omap1_clk_round_rate(struct clk *clk, unsigned long rate); 1968c2ecf20Sopenharmony_ciextern int omap1_clk_set_rate(struct clk *clk, unsigned long rate); 1978c2ecf20Sopenharmony_ciextern unsigned long omap1_ckctl_recalc(struct clk *clk); 1988c2ecf20Sopenharmony_ciextern int omap1_set_sossi_rate(struct clk *clk, unsigned long rate); 1998c2ecf20Sopenharmony_ciextern unsigned long omap1_sossi_recalc(struct clk *clk); 2008c2ecf20Sopenharmony_ciextern unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk); 2018c2ecf20Sopenharmony_ciextern int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate); 2028c2ecf20Sopenharmony_ciextern int omap1_set_uart_rate(struct clk *clk, unsigned long rate); 2038c2ecf20Sopenharmony_ciextern unsigned long omap1_uart_recalc(struct clk *clk); 2048c2ecf20Sopenharmony_ciextern int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate); 2058c2ecf20Sopenharmony_ciextern long omap1_round_ext_clk_rate(struct clk *clk, unsigned long rate); 2068c2ecf20Sopenharmony_ciextern void omap1_init_ext_clk(struct clk *clk); 2078c2ecf20Sopenharmony_ciextern int omap1_select_table_rate(struct clk *clk, unsigned long rate); 2088c2ecf20Sopenharmony_ciextern long omap1_round_to_table_rate(struct clk *clk, unsigned long rate); 2098c2ecf20Sopenharmony_ciextern int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate); 2108c2ecf20Sopenharmony_ciextern long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate); 2118c2ecf20Sopenharmony_ciextern unsigned long omap1_watchdog_recalc(struct clk *clk); 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci#ifdef CONFIG_OMAP_RESET_CLOCKS 2148c2ecf20Sopenharmony_ciextern void omap1_clk_disable_unused(struct clk *clk); 2158c2ecf20Sopenharmony_ci#else 2168c2ecf20Sopenharmony_ci#define omap1_clk_disable_unused NULL 2178c2ecf20Sopenharmony_ci#endif 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_cistruct uart_clk { 2208c2ecf20Sopenharmony_ci struct clk clk; 2218c2ecf20Sopenharmony_ci unsigned long sysc_addr; 2228c2ecf20Sopenharmony_ci}; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci/* Provide a method for preventing idling some ARM IDLECT clocks */ 2258c2ecf20Sopenharmony_cistruct arm_idlect1_clk { 2268c2ecf20Sopenharmony_ci struct clk clk; 2278c2ecf20Sopenharmony_ci unsigned long no_idle_count; 2288c2ecf20Sopenharmony_ci __u8 idlect_shift; 2298c2ecf20Sopenharmony_ci}; 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci/* ARM_CKCTL bit shifts */ 2328c2ecf20Sopenharmony_ci#define CKCTL_PERDIV_OFFSET 0 2338c2ecf20Sopenharmony_ci#define CKCTL_LCDDIV_OFFSET 2 2348c2ecf20Sopenharmony_ci#define CKCTL_ARMDIV_OFFSET 4 2358c2ecf20Sopenharmony_ci#define CKCTL_DSPDIV_OFFSET 6 2368c2ecf20Sopenharmony_ci#define CKCTL_TCDIV_OFFSET 8 2378c2ecf20Sopenharmony_ci#define CKCTL_DSPMMUDIV_OFFSET 10 2388c2ecf20Sopenharmony_ci/*#define ARM_TIMXO 12*/ 2398c2ecf20Sopenharmony_ci#define EN_DSPCK 13 2408c2ecf20Sopenharmony_ci/*#define ARM_INTHCK_SEL 14*/ /* Divide-by-2 for mpu inth_ck */ 2418c2ecf20Sopenharmony_ci/* DSP_CKCTL bit shifts */ 2428c2ecf20Sopenharmony_ci#define CKCTL_DSPPERDIV_OFFSET 0 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci/* ARM_IDLECT2 bit shifts */ 2458c2ecf20Sopenharmony_ci#define EN_WDTCK 0 2468c2ecf20Sopenharmony_ci#define EN_XORPCK 1 2478c2ecf20Sopenharmony_ci#define EN_PERCK 2 2488c2ecf20Sopenharmony_ci#define EN_LCDCK 3 2498c2ecf20Sopenharmony_ci#define EN_LBCK 4 /* Not on 1610/1710 */ 2508c2ecf20Sopenharmony_ci/*#define EN_HSABCK 5*/ 2518c2ecf20Sopenharmony_ci#define EN_APICK 6 2528c2ecf20Sopenharmony_ci#define EN_TIMCK 7 2538c2ecf20Sopenharmony_ci#define DMACK_REQ 8 2548c2ecf20Sopenharmony_ci#define EN_GPIOCK 9 /* Not on 1610/1710 */ 2558c2ecf20Sopenharmony_ci/*#define EN_LBFREECK 10*/ 2568c2ecf20Sopenharmony_ci#define EN_CKOUT_ARM 11 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci/* ARM_IDLECT3 bit shifts */ 2598c2ecf20Sopenharmony_ci#define EN_OCPI_CK 0 2608c2ecf20Sopenharmony_ci#define EN_TC1_CK 2 2618c2ecf20Sopenharmony_ci#define EN_TC2_CK 4 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci/* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */ 2648c2ecf20Sopenharmony_ci#define EN_DSPTIMCK 5 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci/* Various register defines for clock controls scattered around OMAP chip */ 2678c2ecf20Sopenharmony_ci#define SDW_MCLK_INV_BIT 2 /* In ULPD_CLKC_CTRL */ 2688c2ecf20Sopenharmony_ci#define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */ 2698c2ecf20Sopenharmony_ci#define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */ 2708c2ecf20Sopenharmony_ci#define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */ 2718c2ecf20Sopenharmony_ci#define COM_ULPD_PLL_CLK_REQ 1 /* In COM_CLK_DIV_CTRL_SEL */ 2728c2ecf20Sopenharmony_ci#define SWD_CLK_DIV_CTRL_SEL 0xfffe0874 2738c2ecf20Sopenharmony_ci#define COM_CLK_DIV_CTRL_SEL 0xfffe0878 2748c2ecf20Sopenharmony_ci#define SOFT_REQ_REG 0xfffe0834 2758c2ecf20Sopenharmony_ci#define SOFT_REQ_REG2 0xfffe0880 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ciextern __u32 arm_idlect1_mask; 2788c2ecf20Sopenharmony_ciextern struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ciextern const struct clkops clkops_dspck; 2818c2ecf20Sopenharmony_ciextern const struct clkops clkops_dummy; 2828c2ecf20Sopenharmony_ciextern const struct clkops clkops_uart_16xx; 2838c2ecf20Sopenharmony_ciextern const struct clkops clkops_generic; 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci/* used for passing SoC type to omap1_{select,round_to}_table_rate() */ 2868c2ecf20Sopenharmony_ciextern u32 cpu_mask; 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci#endif 289