162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* Copyright (c) 2013, 2018, The Linux Foundation. All rights reserved. */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#ifndef __QCOM_CLK_RCG_H__ 562306a36Sopenharmony_ci#define __QCOM_CLK_RCG_H__ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <linux/clk-provider.h> 862306a36Sopenharmony_ci#include "clk-regmap.h" 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_cistruct freq_tbl { 1362306a36Sopenharmony_ci unsigned long freq; 1462306a36Sopenharmony_ci u8 src; 1562306a36Sopenharmony_ci u8 pre_div; 1662306a36Sopenharmony_ci u16 m; 1762306a36Sopenharmony_ci u16 n; 1862306a36Sopenharmony_ci}; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci/** 2162306a36Sopenharmony_ci * struct mn - M/N:D counter 2262306a36Sopenharmony_ci * @mnctr_en_bit: bit to enable mn counter 2362306a36Sopenharmony_ci * @mnctr_reset_bit: bit to assert mn counter reset 2462306a36Sopenharmony_ci * @mnctr_mode_shift: lowest bit of mn counter mode field 2562306a36Sopenharmony_ci * @n_val_shift: lowest bit of n value field 2662306a36Sopenharmony_ci * @m_val_shift: lowest bit of m value field 2762306a36Sopenharmony_ci * @width: number of bits in m/n/d values 2862306a36Sopenharmony_ci * @reset_in_cc: true if the mnctr_reset_bit is in the CC register 2962306a36Sopenharmony_ci */ 3062306a36Sopenharmony_cistruct mn { 3162306a36Sopenharmony_ci u8 mnctr_en_bit; 3262306a36Sopenharmony_ci u8 mnctr_reset_bit; 3362306a36Sopenharmony_ci u8 mnctr_mode_shift; 3462306a36Sopenharmony_ci#define MNCTR_MODE_DUAL 0x2 3562306a36Sopenharmony_ci#define MNCTR_MODE_MASK 0x3 3662306a36Sopenharmony_ci u8 n_val_shift; 3762306a36Sopenharmony_ci u8 m_val_shift; 3862306a36Sopenharmony_ci u8 width; 3962306a36Sopenharmony_ci bool reset_in_cc; 4062306a36Sopenharmony_ci}; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/** 4362306a36Sopenharmony_ci * struct pre_div - pre-divider 4462306a36Sopenharmony_ci * @pre_div_shift: lowest bit of pre divider field 4562306a36Sopenharmony_ci * @pre_div_width: number of bits in predivider 4662306a36Sopenharmony_ci */ 4762306a36Sopenharmony_cistruct pre_div { 4862306a36Sopenharmony_ci u8 pre_div_shift; 4962306a36Sopenharmony_ci u8 pre_div_width; 5062306a36Sopenharmony_ci}; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/** 5362306a36Sopenharmony_ci * struct src_sel - source selector 5462306a36Sopenharmony_ci * @src_sel_shift: lowest bit of source selection field 5562306a36Sopenharmony_ci * @parent_map: map from software's parent index to hardware's src_sel field 5662306a36Sopenharmony_ci */ 5762306a36Sopenharmony_cistruct src_sel { 5862306a36Sopenharmony_ci u8 src_sel_shift; 5962306a36Sopenharmony_ci#define SRC_SEL_MASK 0x7 6062306a36Sopenharmony_ci const struct parent_map *parent_map; 6162306a36Sopenharmony_ci}; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci/** 6462306a36Sopenharmony_ci * struct clk_rcg - root clock generator 6562306a36Sopenharmony_ci * 6662306a36Sopenharmony_ci * @ns_reg: NS register 6762306a36Sopenharmony_ci * @md_reg: MD register 6862306a36Sopenharmony_ci * @mn: mn counter 6962306a36Sopenharmony_ci * @p: pre divider 7062306a36Sopenharmony_ci * @s: source selector 7162306a36Sopenharmony_ci * @freq_tbl: frequency table 7262306a36Sopenharmony_ci * @clkr: regmap clock handle 7362306a36Sopenharmony_ci * @lock: register lock 7462306a36Sopenharmony_ci */ 7562306a36Sopenharmony_cistruct clk_rcg { 7662306a36Sopenharmony_ci u32 ns_reg; 7762306a36Sopenharmony_ci u32 md_reg; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci struct mn mn; 8062306a36Sopenharmony_ci struct pre_div p; 8162306a36Sopenharmony_ci struct src_sel s; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci const struct freq_tbl *freq_tbl; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci struct clk_regmap clkr; 8662306a36Sopenharmony_ci}; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ciextern const struct clk_ops clk_rcg_ops; 8962306a36Sopenharmony_ciextern const struct clk_ops clk_rcg_floor_ops; 9062306a36Sopenharmony_ciextern const struct clk_ops clk_rcg_bypass_ops; 9162306a36Sopenharmony_ciextern const struct clk_ops clk_rcg_bypass2_ops; 9262306a36Sopenharmony_ciextern const struct clk_ops clk_rcg_pixel_ops; 9362306a36Sopenharmony_ciextern const struct clk_ops clk_rcg_esc_ops; 9462306a36Sopenharmony_ciextern const struct clk_ops clk_rcg_lcc_ops; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci#define to_clk_rcg(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg, clkr) 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci/** 9962306a36Sopenharmony_ci * struct clk_dyn_rcg - root clock generator with glitch free mux 10062306a36Sopenharmony_ci * 10162306a36Sopenharmony_ci * @mux_sel_bit: bit to switch glitch free mux 10262306a36Sopenharmony_ci * @ns_reg: NS0 and NS1 register 10362306a36Sopenharmony_ci * @md_reg: MD0 and MD1 register 10462306a36Sopenharmony_ci * @bank_reg: register to XOR @mux_sel_bit into to switch glitch free mux 10562306a36Sopenharmony_ci * @mn: mn counter (banked) 10662306a36Sopenharmony_ci * @s: source selector (banked) 10762306a36Sopenharmony_ci * @freq_tbl: frequency table 10862306a36Sopenharmony_ci * @clkr: regmap clock handle 10962306a36Sopenharmony_ci * @lock: register lock 11062306a36Sopenharmony_ci */ 11162306a36Sopenharmony_cistruct clk_dyn_rcg { 11262306a36Sopenharmony_ci u32 ns_reg[2]; 11362306a36Sopenharmony_ci u32 md_reg[2]; 11462306a36Sopenharmony_ci u32 bank_reg; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci u8 mux_sel_bit; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci struct mn mn[2]; 11962306a36Sopenharmony_ci struct pre_div p[2]; 12062306a36Sopenharmony_ci struct src_sel s[2]; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci const struct freq_tbl *freq_tbl; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci struct clk_regmap clkr; 12562306a36Sopenharmony_ci}; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ciextern const struct clk_ops clk_dyn_rcg_ops; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci#define to_clk_dyn_rcg(_hw) \ 13062306a36Sopenharmony_ci container_of(to_clk_regmap(_hw), struct clk_dyn_rcg, clkr) 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci/** 13362306a36Sopenharmony_ci * struct clk_rcg2 - root clock generator 13462306a36Sopenharmony_ci * 13562306a36Sopenharmony_ci * @cmd_rcgr: corresponds to *_CMD_RCGR 13662306a36Sopenharmony_ci * @mnd_width: number of bits in m/n/d values 13762306a36Sopenharmony_ci * @hid_width: number of bits in half integer divider 13862306a36Sopenharmony_ci * @safe_src_index: safe src index value 13962306a36Sopenharmony_ci * @parent_map: map from software's parent index to hardware's src_sel field 14062306a36Sopenharmony_ci * @freq_tbl: frequency table 14162306a36Sopenharmony_ci * @clkr: regmap clock handle 14262306a36Sopenharmony_ci * @cfg_off: defines the cfg register offset from the CMD_RCGR + CFG_REG 14362306a36Sopenharmony_ci * @parked_cfg: cached value of the CFG register for parked RCGs 14462306a36Sopenharmony_ci * @hw_clk_ctrl: whether to enable hardware clock control 14562306a36Sopenharmony_ci */ 14662306a36Sopenharmony_cistruct clk_rcg2 { 14762306a36Sopenharmony_ci u32 cmd_rcgr; 14862306a36Sopenharmony_ci u8 mnd_width; 14962306a36Sopenharmony_ci u8 hid_width; 15062306a36Sopenharmony_ci u8 safe_src_index; 15162306a36Sopenharmony_ci const struct parent_map *parent_map; 15262306a36Sopenharmony_ci const struct freq_tbl *freq_tbl; 15362306a36Sopenharmony_ci struct clk_regmap clkr; 15462306a36Sopenharmony_ci u8 cfg_off; 15562306a36Sopenharmony_ci u32 parked_cfg; 15662306a36Sopenharmony_ci bool hw_clk_ctrl; 15762306a36Sopenharmony_ci}; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci#define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr) 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_cistruct clk_rcg2_gfx3d { 16262306a36Sopenharmony_ci u8 div; 16362306a36Sopenharmony_ci struct clk_rcg2 rcg; 16462306a36Sopenharmony_ci struct clk_hw **hws; 16562306a36Sopenharmony_ci}; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci#define to_clk_rcg2_gfx3d(_hw) \ 16862306a36Sopenharmony_ci container_of(to_clk_rcg2(_hw), struct clk_rcg2_gfx3d, rcg) 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ciextern const struct clk_ops clk_rcg2_ops; 17162306a36Sopenharmony_ciextern const struct clk_ops clk_rcg2_floor_ops; 17262306a36Sopenharmony_ciextern const struct clk_ops clk_rcg2_mux_closest_ops; 17362306a36Sopenharmony_ciextern const struct clk_ops clk_edp_pixel_ops; 17462306a36Sopenharmony_ciextern const struct clk_ops clk_byte_ops; 17562306a36Sopenharmony_ciextern const struct clk_ops clk_byte2_ops; 17662306a36Sopenharmony_ciextern const struct clk_ops clk_pixel_ops; 17762306a36Sopenharmony_ciextern const struct clk_ops clk_gfx3d_ops; 17862306a36Sopenharmony_ciextern const struct clk_ops clk_rcg2_shared_ops; 17962306a36Sopenharmony_ciextern const struct clk_ops clk_dp_ops; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_cistruct clk_rcg_dfs_data { 18262306a36Sopenharmony_ci struct clk_rcg2 *rcg; 18362306a36Sopenharmony_ci struct clk_init_data *init; 18462306a36Sopenharmony_ci}; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci#define DEFINE_RCG_DFS(r) \ 18762306a36Sopenharmony_ci { .rcg = &r, .init = &r##_init } 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ciextern int qcom_cc_register_rcg_dfs(struct regmap *regmap, 19062306a36Sopenharmony_ci const struct clk_rcg_dfs_data *rcgs, 19162306a36Sopenharmony_ci size_t len); 19262306a36Sopenharmony_ci#endif 193