1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * Copyright (c) 2017 Rockchip Electronics Co. Ltd. 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify 5*4882a593Smuzhiyun * it under the terms of the GNU General Public License as published by 6*4882a593Smuzhiyun * the Free Software Foundation; either version 2 of the License, or 7*4882a593Smuzhiyun * (at your option) any later version. 8*4882a593Smuzhiyun * 9*4882a593Smuzhiyun * This program is distributed in the hope that it will be useful, 10*4882a593Smuzhiyun * but WITHOUT ANY WARRANTY; without even the implied warranty of 11*4882a593Smuzhiyun * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12*4882a593Smuzhiyun * GNU General Public License for more details. 13*4882a593Smuzhiyun */ 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun #ifndef __CLK_REGMAP_H__ 16*4882a593Smuzhiyun #define __CLK_REGMAP_H__ 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun #include <linux/regmap.h> 19*4882a593Smuzhiyun #include <linux/kernel.h> 20*4882a593Smuzhiyun #include <linux/module.h> 21*4882a593Smuzhiyun #include <linux/platform_device.h> 22*4882a593Smuzhiyun #include <linux/clk-provider.h> 23*4882a593Smuzhiyun #include <linux/device.h> 24*4882a593Smuzhiyun #include <linux/delay.h> 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun #define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l))) 27*4882a593Smuzhiyun #define HIWORD_UPDATE(v, h, l) (((v) << (l)) | (GENMASK((h), (l)) << 16)) 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun struct clk_pll_data { 30*4882a593Smuzhiyun unsigned int id; 31*4882a593Smuzhiyun const char *name; 32*4882a593Smuzhiyun const char *parent_name; 33*4882a593Smuzhiyun u32 reg; 34*4882a593Smuzhiyun u8 pd_shift; 35*4882a593Smuzhiyun u8 dsmpd_shift; 36*4882a593Smuzhiyun u8 lock_shift; 37*4882a593Smuzhiyun unsigned long flags; 38*4882a593Smuzhiyun }; 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun #define PLL(_id, _name, _parent_name, _reg, _pd_shift, _dsmpd_shift, \ 41*4882a593Smuzhiyun _lock_shift, _flags) \ 42*4882a593Smuzhiyun { \ 43*4882a593Smuzhiyun .id = _id, \ 44*4882a593Smuzhiyun .name = _name, \ 45*4882a593Smuzhiyun .parent_name = _parent_name, \ 46*4882a593Smuzhiyun .reg = _reg, \ 47*4882a593Smuzhiyun .pd_shift = _pd_shift, \ 48*4882a593Smuzhiyun .dsmpd_shift = _dsmpd_shift, \ 49*4882a593Smuzhiyun .lock_shift = _lock_shift, \ 50*4882a593Smuzhiyun .flags = _flags, \ 51*4882a593Smuzhiyun } 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun #define RK618_PLL(_id, _name, _parent_name, _reg, _flags) \ 54*4882a593Smuzhiyun PLL(_id, _name, _parent_name, _reg, 10, 9, 15, _flags) 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun struct clk_mux_data { 57*4882a593Smuzhiyun unsigned int id; 58*4882a593Smuzhiyun const char *name; 59*4882a593Smuzhiyun const char *const *parent_names; 60*4882a593Smuzhiyun u8 num_parents; 61*4882a593Smuzhiyun u32 reg; 62*4882a593Smuzhiyun u8 shift; 63*4882a593Smuzhiyun u8 width; 64*4882a593Smuzhiyun unsigned long flags; 65*4882a593Smuzhiyun }; 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun #define MUX(_id, _name, _parent_names, _reg, _shift, _width, _flags) \ 68*4882a593Smuzhiyun { \ 69*4882a593Smuzhiyun .id = _id, \ 70*4882a593Smuzhiyun .name = _name, \ 71*4882a593Smuzhiyun .parent_names = _parent_names, \ 72*4882a593Smuzhiyun .num_parents = ARRAY_SIZE(_parent_names), \ 73*4882a593Smuzhiyun .reg = _reg, \ 74*4882a593Smuzhiyun .shift = _shift, \ 75*4882a593Smuzhiyun .width = _width, \ 76*4882a593Smuzhiyun .flags = _flags, \ 77*4882a593Smuzhiyun } 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun struct clk_gate_data { 80*4882a593Smuzhiyun unsigned int id; 81*4882a593Smuzhiyun const char *name; 82*4882a593Smuzhiyun const char *parent_name; 83*4882a593Smuzhiyun u32 reg; 84*4882a593Smuzhiyun u8 shift; 85*4882a593Smuzhiyun unsigned long flags; 86*4882a593Smuzhiyun }; 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun #define GATE(_id, _name, _parent_name, _reg, _shift, _flags) \ 89*4882a593Smuzhiyun { \ 90*4882a593Smuzhiyun .id = _id, \ 91*4882a593Smuzhiyun .name = _name, \ 92*4882a593Smuzhiyun .parent_name = _parent_name, \ 93*4882a593Smuzhiyun .reg = _reg, \ 94*4882a593Smuzhiyun .shift = _shift, \ 95*4882a593Smuzhiyun .flags = _flags, \ 96*4882a593Smuzhiyun } 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun struct clk_divider_data { 99*4882a593Smuzhiyun unsigned int id; 100*4882a593Smuzhiyun const char *name; 101*4882a593Smuzhiyun const char *parent_name; 102*4882a593Smuzhiyun u32 reg; 103*4882a593Smuzhiyun u8 shift; 104*4882a593Smuzhiyun u8 width; 105*4882a593Smuzhiyun unsigned long flags; 106*4882a593Smuzhiyun }; 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun #define DIV(_id, _name, _parent_name, _reg, _shift, _width, _flags) \ 109*4882a593Smuzhiyun { \ 110*4882a593Smuzhiyun .id = _id, \ 111*4882a593Smuzhiyun .name = _name, \ 112*4882a593Smuzhiyun .parent_name = _parent_name, \ 113*4882a593Smuzhiyun .reg = _reg, \ 114*4882a593Smuzhiyun .shift = _shift, \ 115*4882a593Smuzhiyun .width = _width, \ 116*4882a593Smuzhiyun .flags = _flags, \ 117*4882a593Smuzhiyun } 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun struct clk_composite_data { 120*4882a593Smuzhiyun unsigned int id; 121*4882a593Smuzhiyun const char *name; 122*4882a593Smuzhiyun const char *const *parent_names; 123*4882a593Smuzhiyun u8 num_parents; 124*4882a593Smuzhiyun u32 mux_reg; 125*4882a593Smuzhiyun u8 mux_shift; 126*4882a593Smuzhiyun u8 mux_width; 127*4882a593Smuzhiyun u32 div_reg; 128*4882a593Smuzhiyun u8 div_shift; 129*4882a593Smuzhiyun u8 div_width; 130*4882a593Smuzhiyun u8 div_flags; 131*4882a593Smuzhiyun u32 gate_reg; 132*4882a593Smuzhiyun u8 gate_shift; 133*4882a593Smuzhiyun unsigned long flags; 134*4882a593Smuzhiyun }; 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun #define COMPOSITE(_id, _name, _parent_names, \ 137*4882a593Smuzhiyun _mux_reg, _mux_shift, _mux_width, \ 138*4882a593Smuzhiyun _div_reg, _div_shift, _div_width, \ 139*4882a593Smuzhiyun _gate_reg, _gate_shift, _flags) \ 140*4882a593Smuzhiyun { \ 141*4882a593Smuzhiyun .id = _id, \ 142*4882a593Smuzhiyun .name = _name, \ 143*4882a593Smuzhiyun .parent_names = _parent_names, \ 144*4882a593Smuzhiyun .num_parents = ARRAY_SIZE(_parent_names), \ 145*4882a593Smuzhiyun .mux_reg = _mux_reg, \ 146*4882a593Smuzhiyun .mux_shift = _mux_shift, \ 147*4882a593Smuzhiyun .mux_width = _mux_width, \ 148*4882a593Smuzhiyun .div_reg = _div_reg, \ 149*4882a593Smuzhiyun .div_shift = _div_shift, \ 150*4882a593Smuzhiyun .div_width = _div_width, \ 151*4882a593Smuzhiyun .div_flags = CLK_DIVIDER_HIWORD_MASK, \ 152*4882a593Smuzhiyun .gate_reg = _gate_reg, \ 153*4882a593Smuzhiyun .gate_shift = _gate_shift, \ 154*4882a593Smuzhiyun .flags = _flags, \ 155*4882a593Smuzhiyun } 156*4882a593Smuzhiyun 157*4882a593Smuzhiyun #define COMPOSITE_NOMUX(_id, _name, _parent_name, \ 158*4882a593Smuzhiyun _div_reg, _div_shift, _div_width, \ 159*4882a593Smuzhiyun _gate_reg, _gate_shift, _flags) \ 160*4882a593Smuzhiyun { \ 161*4882a593Smuzhiyun .id = _id, \ 162*4882a593Smuzhiyun .name = _name, \ 163*4882a593Smuzhiyun .parent_names = (const char *[]){ _parent_name }, \ 164*4882a593Smuzhiyun .num_parents = 1, \ 165*4882a593Smuzhiyun .div_reg = _div_reg, \ 166*4882a593Smuzhiyun .div_shift = _div_shift, \ 167*4882a593Smuzhiyun .div_width = _div_width, \ 168*4882a593Smuzhiyun .div_flags = CLK_DIVIDER_HIWORD_MASK, \ 169*4882a593Smuzhiyun .gate_reg = _gate_reg, \ 170*4882a593Smuzhiyun .gate_shift = _gate_shift, \ 171*4882a593Smuzhiyun .flags = _flags, \ 172*4882a593Smuzhiyun } 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun #define COMPOSITE_NODIV(_id, _name, _parent_names, \ 175*4882a593Smuzhiyun _mux_reg, _mux_shift, _mux_width, \ 176*4882a593Smuzhiyun _gate_reg, _gate_shift, _flags) \ 177*4882a593Smuzhiyun COMPOSITE(_id, _name, _parent_names, \ 178*4882a593Smuzhiyun _mux_reg, _mux_shift, _mux_width, \ 179*4882a593Smuzhiyun 0, 0, 0, \ 180*4882a593Smuzhiyun _gate_reg, _gate_shift, _flags) 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun #define COMPOSITE_FRAC(_id, _name, _parent_names, \ 183*4882a593Smuzhiyun _mux_reg, _mux_shift, _mux_width, \ 184*4882a593Smuzhiyun _div_reg, \ 185*4882a593Smuzhiyun _gate_reg, _gate_shift, _flags) \ 186*4882a593Smuzhiyun { \ 187*4882a593Smuzhiyun .id = _id, \ 188*4882a593Smuzhiyun .name = _name, \ 189*4882a593Smuzhiyun .parent_names = _parent_names, \ 190*4882a593Smuzhiyun .num_parents = ARRAY_SIZE(_parent_names), \ 191*4882a593Smuzhiyun .mux_reg = _mux_reg, \ 192*4882a593Smuzhiyun .mux_shift = _mux_shift, \ 193*4882a593Smuzhiyun .mux_width = _mux_width, \ 194*4882a593Smuzhiyun .div_reg = _div_reg, \ 195*4882a593Smuzhiyun .gate_reg = _gate_reg, \ 196*4882a593Smuzhiyun .gate_shift = _gate_shift, \ 197*4882a593Smuzhiyun .flags = _flags, \ 198*4882a593Smuzhiyun } 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun #define COMPOSITE_FRAC_NOMUX(_id, _name, _parent_name, \ 201*4882a593Smuzhiyun _div_reg, \ 202*4882a593Smuzhiyun _gate_reg, _gate_shift, _flags) \ 203*4882a593Smuzhiyun { \ 204*4882a593Smuzhiyun .id = _id, \ 205*4882a593Smuzhiyun .name = _name, \ 206*4882a593Smuzhiyun .parent_names = (const char *[]){ _parent_name }, \ 207*4882a593Smuzhiyun .num_parents = 1, \ 208*4882a593Smuzhiyun .div_reg = _div_reg, \ 209*4882a593Smuzhiyun .gate_reg = _gate_reg, \ 210*4882a593Smuzhiyun .gate_shift = _gate_shift, \ 211*4882a593Smuzhiyun .flags = _flags, \ 212*4882a593Smuzhiyun } 213*4882a593Smuzhiyun 214*4882a593Smuzhiyun #define COMPOSITE_FRAC_NOGATE(_id, _name, _parent_names, \ 215*4882a593Smuzhiyun _mux_reg, _mux_shift, _mux_width, \ 216*4882a593Smuzhiyun _div_reg, \ 217*4882a593Smuzhiyun _flags) \ 218*4882a593Smuzhiyun COMPOSITE_FRAC(_id, _name, _parent_names, \ 219*4882a593Smuzhiyun _mux_reg, _mux_shift, _mux_width, \ 220*4882a593Smuzhiyun _div_reg, 0, 0, _flags) 221*4882a593Smuzhiyun 222*4882a593Smuzhiyun struct clk_regmap_fractional_divider { 223*4882a593Smuzhiyun struct clk_hw hw; 224*4882a593Smuzhiyun struct device *dev; 225*4882a593Smuzhiyun struct regmap *regmap; 226*4882a593Smuzhiyun u32 reg; 227*4882a593Smuzhiyun u8 mshift; 228*4882a593Smuzhiyun u8 mwidth; 229*4882a593Smuzhiyun u32 mmask; 230*4882a593Smuzhiyun u8 nshift; 231*4882a593Smuzhiyun u8 nwidth; 232*4882a593Smuzhiyun u32 nmask; 233*4882a593Smuzhiyun }; 234*4882a593Smuzhiyun 235*4882a593Smuzhiyun struct clk_regmap_divider { 236*4882a593Smuzhiyun struct clk_hw hw; 237*4882a593Smuzhiyun struct device *dev; 238*4882a593Smuzhiyun struct regmap *regmap; 239*4882a593Smuzhiyun u32 reg; 240*4882a593Smuzhiyun u8 shift; 241*4882a593Smuzhiyun u8 width; 242*4882a593Smuzhiyun }; 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun struct clk_regmap_gate { 245*4882a593Smuzhiyun struct clk_hw hw; 246*4882a593Smuzhiyun struct device *dev; 247*4882a593Smuzhiyun struct regmap *regmap; 248*4882a593Smuzhiyun u32 reg; 249*4882a593Smuzhiyun u8 shift; 250*4882a593Smuzhiyun }; 251*4882a593Smuzhiyun 252*4882a593Smuzhiyun struct clk_regmap_mux { 253*4882a593Smuzhiyun struct clk_hw hw; 254*4882a593Smuzhiyun struct device *dev; 255*4882a593Smuzhiyun struct regmap *regmap; 256*4882a593Smuzhiyun u32 reg; 257*4882a593Smuzhiyun u32 mask; 258*4882a593Smuzhiyun u8 shift; 259*4882a593Smuzhiyun }; 260*4882a593Smuzhiyun 261*4882a593Smuzhiyun extern const struct clk_ops clk_regmap_mux_ops; 262*4882a593Smuzhiyun extern const struct clk_ops clk_regmap_divider_ops; 263*4882a593Smuzhiyun extern const struct clk_ops clk_regmap_gate_ops; 264*4882a593Smuzhiyun extern const struct clk_ops clk_regmap_fractional_divider_ops; 265*4882a593Smuzhiyun 266*4882a593Smuzhiyun struct clk * 267*4882a593Smuzhiyun devm_clk_regmap_register_pll(struct device *dev, const char *name, 268*4882a593Smuzhiyun const char *parent_name, 269*4882a593Smuzhiyun struct regmap *regmap, u32 reg, u8 pd_shift, 270*4882a593Smuzhiyun u8 dsmpd_shift, u8 lock_shift, 271*4882a593Smuzhiyun unsigned long flags); 272*4882a593Smuzhiyun 273*4882a593Smuzhiyun struct clk * 274*4882a593Smuzhiyun devm_clk_regmap_register_mux(struct device *dev, const char *name, 275*4882a593Smuzhiyun const char * const *parent_names, u8 num_parents, 276*4882a593Smuzhiyun struct regmap *regmap, u32 reg, u8 shift, u8 width, 277*4882a593Smuzhiyun unsigned long flags); 278*4882a593Smuzhiyun 279*4882a593Smuzhiyun struct clk * 280*4882a593Smuzhiyun devm_clk_regmap_register_divider(struct device *dev, const char *name, 281*4882a593Smuzhiyun const char *parent_name, struct regmap *regmap, 282*4882a593Smuzhiyun u32 reg, u8 shift, u8 width, 283*4882a593Smuzhiyun unsigned long flags); 284*4882a593Smuzhiyun 285*4882a593Smuzhiyun struct clk * 286*4882a593Smuzhiyun devm_clk_regmap_register_gate(struct device *dev, const char *name, 287*4882a593Smuzhiyun const char *parent_name, 288*4882a593Smuzhiyun struct regmap *regmap, u32 reg, u8 shift, 289*4882a593Smuzhiyun unsigned long flags); 290*4882a593Smuzhiyun 291*4882a593Smuzhiyun struct clk * 292*4882a593Smuzhiyun devm_clk_regmap_register_fractional_divider(struct device *dev, 293*4882a593Smuzhiyun const char *name, 294*4882a593Smuzhiyun const char *parent_name, 295*4882a593Smuzhiyun struct regmap *regmap, 296*4882a593Smuzhiyun u32 reg, unsigned long flags); 297*4882a593Smuzhiyun 298*4882a593Smuzhiyun struct clk * 299*4882a593Smuzhiyun devm_clk_regmap_register_composite(struct device *dev, const char *name, 300*4882a593Smuzhiyun const char *const *parent_names, 301*4882a593Smuzhiyun u8 num_parents, struct regmap *regmap, 302*4882a593Smuzhiyun u32 mux_reg, u8 mux_shift, u8 mux_width, 303*4882a593Smuzhiyun u32 div_reg, u8 div_shift, u8 div_width, 304*4882a593Smuzhiyun u8 div_flags, 305*4882a593Smuzhiyun u32 gate_reg, u8 gate_shift, 306*4882a593Smuzhiyun unsigned long flags); 307*4882a593Smuzhiyun 308*4882a593Smuzhiyun #endif 309