18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci// 38c2ecf20Sopenharmony_ci// Spreadtrum divider clock driver 48c2ecf20Sopenharmony_ci// 58c2ecf20Sopenharmony_ci// Copyright (C) 2017 Spreadtrum, Inc. 68c2ecf20Sopenharmony_ci// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#ifndef _SPRD_DIV_H_ 98c2ecf20Sopenharmony_ci#define _SPRD_DIV_H_ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include "common.h" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci/** 148c2ecf20Sopenharmony_ci * struct sprd_div_internal - Internal divider description 158c2ecf20Sopenharmony_ci * @shift: Bit offset of the divider in its register 168c2ecf20Sopenharmony_ci * @width: Width of the divider field in its register 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * That structure represents a single divider, and is meant to be 198c2ecf20Sopenharmony_ci * embedded in other structures representing the various clock 208c2ecf20Sopenharmony_ci * classes. 218c2ecf20Sopenharmony_ci */ 228c2ecf20Sopenharmony_cistruct sprd_div_internal { 238c2ecf20Sopenharmony_ci u8 shift; 248c2ecf20Sopenharmony_ci u8 width; 258c2ecf20Sopenharmony_ci}; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#define _SPRD_DIV_CLK(_shift, _width) \ 288c2ecf20Sopenharmony_ci { \ 298c2ecf20Sopenharmony_ci .shift = _shift, \ 308c2ecf20Sopenharmony_ci .width = _width, \ 318c2ecf20Sopenharmony_ci } 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_cistruct sprd_div { 348c2ecf20Sopenharmony_ci struct sprd_div_internal div; 358c2ecf20Sopenharmony_ci struct sprd_clk_common common; 368c2ecf20Sopenharmony_ci}; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci#define SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ 398c2ecf20Sopenharmony_ci _shift, _width, _flags, _fn) \ 408c2ecf20Sopenharmony_ci struct sprd_div _struct = { \ 418c2ecf20Sopenharmony_ci .div = _SPRD_DIV_CLK(_shift, _width), \ 428c2ecf20Sopenharmony_ci .common = { \ 438c2ecf20Sopenharmony_ci .regmap = NULL, \ 448c2ecf20Sopenharmony_ci .reg = _reg, \ 458c2ecf20Sopenharmony_ci .hw.init = _fn(_name, _parent, \ 468c2ecf20Sopenharmony_ci &sprd_div_ops, _flags), \ 478c2ecf20Sopenharmony_ci } \ 488c2ecf20Sopenharmony_ci } 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci#define SPRD_DIV_CLK(_struct, _name, _parent, _reg, \ 518c2ecf20Sopenharmony_ci _shift, _width, _flags) \ 528c2ecf20Sopenharmony_ci SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ 538c2ecf20Sopenharmony_ci _shift, _width, _flags, CLK_HW_INIT) 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#define SPRD_DIV_CLK_HW(_struct, _name, _parent, _reg, \ 568c2ecf20Sopenharmony_ci _shift, _width, _flags) \ 578c2ecf20Sopenharmony_ci SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ 588c2ecf20Sopenharmony_ci _shift, _width, _flags, CLK_HW_INIT_HW) 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistatic inline struct sprd_div *hw_to_sprd_div(const struct clk_hw *hw) 618c2ecf20Sopenharmony_ci{ 628c2ecf20Sopenharmony_ci struct sprd_clk_common *common = hw_to_sprd_clk_common(hw); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci return container_of(common, struct sprd_div, common); 658c2ecf20Sopenharmony_ci} 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_cilong sprd_div_helper_round_rate(struct sprd_clk_common *common, 688c2ecf20Sopenharmony_ci const struct sprd_div_internal *div, 698c2ecf20Sopenharmony_ci unsigned long rate, 708c2ecf20Sopenharmony_ci unsigned long *parent_rate); 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ciunsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common, 738c2ecf20Sopenharmony_ci const struct sprd_div_internal *div, 748c2ecf20Sopenharmony_ci unsigned long parent_rate); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ciint sprd_div_helper_set_rate(const struct sprd_clk_common *common, 778c2ecf20Sopenharmony_ci const struct sprd_div_internal *div, 788c2ecf20Sopenharmony_ci unsigned long rate, 798c2ecf20Sopenharmony_ci unsigned long parent_rate); 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ciextern const struct clk_ops sprd_div_ops; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci#endif /* _SPRD_DIV_H_ */ 84