1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Copyright (C) 2023 Inochi Amaoto <inochiama@outlook.com> 4 */ 5 6#ifndef _CLK_SOPHGO_CV1800_PLL_H_ 7#define _CLK_SOPHGO_CV1800_PLL_H_ 8 9#include "clk-cv18xx-common.h" 10 11struct cv1800_clk_pll_limit { 12 struct { 13 u8 min; 14 u8 max; 15 } pre_div, div, post_div, ictrl, mode; 16}; 17 18#define _CV1800_PLL_LIMIT(_min, _max) \ 19 { \ 20 .min = _min, \ 21 .max = _max, \ 22 } \ 23 24#define for_each_pll_limit_range(_var, _restrict) \ 25 for (_var = (_restrict)->min; _var <= (_restrict)->max; _var++) 26 27struct cv1800_clk_pll_synthesizer { 28 struct cv1800_clk_regbit en; 29 struct cv1800_clk_regbit clk_half; 30 u32 ctrl; 31 u32 set; 32}; 33 34#define _PLL_PRE_DIV_SEL_FIELD GENMASK(6, 0) 35#define _PLL_POST_DIV_SEL_FIELD GENMASK(14, 8) 36#define _PLL_SEL_MODE_FIELD GENMASK(16, 15) 37#define _PLL_DIV_SEL_FIELD GENMASK(23, 17) 38#define _PLL_ICTRL_FIELD GENMASK(26, 24) 39 40#define _PLL_ALL_FIELD_MASK \ 41 (_PLL_PRE_DIV_SEL_FIELD | \ 42 _PLL_POST_DIV_SEL_FIELD | \ 43 _PLL_SEL_MODE_FIELD | \ 44 _PLL_DIV_SEL_FIELD | \ 45 _PLL_ICTRL_FIELD) 46 47#define PLL_COPY_REG(_dest, _src) \ 48 (((_dest) & (~_PLL_ALL_FIELD_MASK)) | ((_src) & _PLL_ALL_FIELD_MASK)) 49 50#define PLL_GET_PRE_DIV_SEL(_reg) \ 51 FIELD_GET(_PLL_PRE_DIV_SEL_FIELD, (_reg)) 52#define PLL_GET_POST_DIV_SEL(_reg) \ 53 FIELD_GET(_PLL_POST_DIV_SEL_FIELD, (_reg)) 54#define PLL_GET_SEL_MODE(_reg) \ 55 FIELD_GET(_PLL_SEL_MODE_FIELD, (_reg)) 56#define PLL_GET_DIV_SEL(_reg) \ 57 FIELD_GET(_PLL_DIV_SEL_FIELD, (_reg)) 58#define PLL_GET_ICTRL(_reg) \ 59 FIELD_GET(_PLL_ICTRL_FIELD, (_reg)) 60 61#define PLL_SET_PRE_DIV_SEL(_reg, _val) \ 62 _CV1800_SET_FIELD((_reg), (_val), _PLL_PRE_DIV_SEL_FIELD) 63#define PLL_SET_POST_DIV_SEL(_reg, _val) \ 64 _CV1800_SET_FIELD((_reg), (_val), _PLL_POST_DIV_SEL_FIELD) 65#define PLL_SET_SEL_MODE(_reg, _val) \ 66 _CV1800_SET_FIELD((_reg), (_val), _PLL_SEL_MODE_FIELD) 67#define PLL_SET_DIV_SEL(_reg, _val) \ 68 _CV1800_SET_FIELD((_reg), (_val), _PLL_DIV_SEL_FIELD) 69#define PLL_SET_ICTRL(_reg, _val) \ 70 _CV1800_SET_FIELD((_reg), (_val), _PLL_ICTRL_FIELD) 71 72struct cv1800_clk_pll { 73 struct cv1800_clk_common common; 74 u32 pll_reg; 75 struct cv1800_clk_regbit pll_pwd; 76 struct cv1800_clk_regbit pll_status; 77 const struct cv1800_clk_pll_limit *pll_limit; 78 struct cv1800_clk_pll_synthesizer *pll_syn; 79}; 80 81#define CV1800_INTEGRAL_PLL(_name, _parent, _pll_reg, \ 82 _pll_pwd_reg, _pll_pwd_shift, \ 83 _pll_status_reg, _pll_status_shift, \ 84 _pll_limit, _flags) \ 85 struct cv1800_clk_pll _name = { \ 86 .common = CV1800_CLK_COMMON(#_name, _parent, \ 87 &cv1800_clk_ipll_ops,\ 88 _flags), \ 89 .pll_reg = _pll_reg, \ 90 .pll_pwd = CV1800_CLK_BIT(_pll_pwd_reg, \ 91 _pll_pwd_shift), \ 92 .pll_status = CV1800_CLK_BIT(_pll_status_reg, \ 93 _pll_status_shift), \ 94 .pll_limit = _pll_limit, \ 95 .pll_syn = NULL, \ 96 } 97 98#define CV1800_FACTIONAL_PLL(_name, _parent, _pll_reg, \ 99 _pll_pwd_reg, _pll_pwd_shift, \ 100 _pll_status_reg, _pll_status_shift, \ 101 _pll_limit, _pll_syn, _flags) \ 102 struct cv1800_clk_pll _name = { \ 103 .common = CV1800_CLK_COMMON(#_name, _parent, \ 104 &cv1800_clk_fpll_ops,\ 105 _flags), \ 106 .pll_reg = _pll_reg, \ 107 .pll_pwd = CV1800_CLK_BIT(_pll_pwd_reg, \ 108 _pll_pwd_shift), \ 109 .pll_status = CV1800_CLK_BIT(_pll_status_reg, \ 110 _pll_status_shift), \ 111 .pll_limit = _pll_limit, \ 112 .pll_syn = _pll_syn, \ 113 } 114 115extern const struct clk_ops cv1800_clk_ipll_ops; 116extern const struct clk_ops cv1800_clk_fpll_ops; 117 118#endif // _CLK_SOPHGO_CV1800_PLL_H_ 119