Chunyan Zhang | 3e37b00 | 2017-12-07 20:57:10 +0800 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | // |
| 3 | // Spreadtrum pll clock driver |
| 4 | // |
| 5 | // Copyright (C) 2015~2017 Spreadtrum, Inc. |
| 6 | // Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> |
| 7 | |
| 8 | #ifndef _SPRD_PLL_H_ |
| 9 | #define _SPRD_PLL_H_ |
| 10 | |
| 11 | #include "common.h" |
| 12 | |
| 13 | struct reg_cfg { |
| 14 | u32 val; |
| 15 | u32 msk; |
| 16 | }; |
| 17 | |
| 18 | struct clk_bit_field { |
| 19 | u8 shift; |
| 20 | u8 width; |
| 21 | }; |
| 22 | |
| 23 | enum { |
| 24 | PLL_LOCK_DONE, |
| 25 | PLL_DIV_S, |
| 26 | PLL_MOD_EN, |
| 27 | PLL_SDM_EN, |
| 28 | PLL_REFIN, |
| 29 | PLL_IBIAS, |
| 30 | PLL_N, |
| 31 | PLL_NINT, |
| 32 | PLL_KINT, |
| 33 | PLL_PREDIV, |
| 34 | PLL_POSTDIV, |
| 35 | |
| 36 | PLL_FACT_MAX |
| 37 | }; |
| 38 | |
| 39 | /* |
| 40 | * struct sprd_pll - definition of adjustable pll clock |
| 41 | * |
| 42 | * @reg: registers used to set the configuration of pll clock, |
| 43 | * reg[0] shows how many registers this pll clock uses. |
| 44 | * @itable: pll ibias table, itable[0] means how many items this |
| 45 | * table includes |
| 46 | * @udelay delay time after setting rate |
| 47 | * @factors used to calculate the pll clock rate |
| 48 | * @fvco: fvco threshold rate |
| 49 | * @fflag: fvco flag |
| 50 | */ |
| 51 | struct sprd_pll { |
| 52 | u32 regs_num; |
| 53 | const u64 *itable; |
| 54 | const struct clk_bit_field *factors; |
| 55 | u16 udelay; |
| 56 | u16 k1; |
| 57 | u16 k2; |
| 58 | u16 fflag; |
| 59 | u64 fvco; |
| 60 | |
| 61 | struct sprd_clk_common common; |
| 62 | }; |
| 63 | |
| 64 | #define SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \ |
| 65 | _regs_num, _itable, _factors, \ |
| 66 | _udelay, _k1, _k2, _fflag, _fvco) \ |
| 67 | struct sprd_pll _struct = { \ |
| 68 | .regs_num = _regs_num, \ |
| 69 | .itable = _itable, \ |
| 70 | .factors = _factors, \ |
| 71 | .udelay = _udelay, \ |
| 72 | .k1 = _k1, \ |
| 73 | .k2 = _k2, \ |
| 74 | .fflag = _fflag, \ |
| 75 | .fvco = _fvco, \ |
| 76 | .common = { \ |
| 77 | .regmap = NULL, \ |
| 78 | .reg = _reg, \ |
| 79 | .hw.init = CLK_HW_INIT(_name, \ |
| 80 | _parent, \ |
| 81 | &sprd_pll_ops, \ |
| 82 | 0), \ |
| 83 | }, \ |
| 84 | } |
| 85 | |
| 86 | #define SPRD_PLL_WITH_ITABLE_K(_struct, _name, _parent, _reg, \ |
| 87 | _regs_num, _itable, _factors, \ |
| 88 | _udelay, _k1, _k2) \ |
| 89 | SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \ |
| 90 | _regs_num, _itable, _factors, \ |
| 91 | _udelay, _k1, _k2, 0, 0) |
| 92 | |
| 93 | #define SPRD_PLL_WITH_ITABLE_1K(_struct, _name, _parent, _reg, \ |
| 94 | _regs_num, _itable, _factors, _udelay) \ |
| 95 | SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \ |
| 96 | _regs_num, _itable, _factors, \ |
| 97 | _udelay, 1000, 1000, 0, 0) |
| 98 | |
| 99 | static inline struct sprd_pll *hw_to_sprd_pll(struct clk_hw *hw) |
| 100 | { |
| 101 | struct sprd_clk_common *common = hw_to_sprd_clk_common(hw); |
| 102 | |
| 103 | return container_of(common, struct sprd_pll, common); |
| 104 | } |
| 105 | |
| 106 | extern const struct clk_ops sprd_pll_ops; |
| 107 | |
| 108 | #endif /* _SPRD_PLL_H_ */ |