0001
0002
0003
0004
0005
0006
0007 #ifndef _CLK_KONA_H
0008 #define _CLK_KONA_H
0009
0010 #include <linux/kernel.h>
0011 #include <linux/list.h>
0012 #include <linux/spinlock.h>
0013 #include <linux/slab.h>
0014 #include <linux/device.h>
0015 #include <linux/of.h>
0016 #include <linux/clk-provider.h>
0017
0018 #define BILLION 1000000000
0019
0020
0021 #define PARENT_COUNT_MAX ((u32)U8_MAX)
0022
0023 #define BAD_CLK_INDEX U8_MAX
0024 #define BAD_CLK_NAME ((const char *)-1)
0025
0026 #define BAD_SCALED_DIV_VALUE U64_MAX
0027
0028
0029
0030
0031
0032 #define FLAG(type, flag) BCM_CLK_ ## type ## _FLAGS_ ## flag
0033 #define FLAG_SET(obj, type, flag) ((obj)->flags |= FLAG(type, flag))
0034 #define FLAG_CLEAR(obj, type, flag) ((obj)->flags &= ~(FLAG(type, flag)))
0035 #define FLAG_FLIP(obj, type, flag) ((obj)->flags ^= FLAG(type, flag))
0036 #define FLAG_TEST(obj, type, flag) (!!((obj)->flags & FLAG(type, flag)))
0037
0038
0039
0040 #define ccu_policy_exists(ccu_policy) ((ccu_policy)->enable.offset != 0)
0041
0042
0043
0044 #define policy_exists(policy) ((policy)->offset != 0)
0045
0046 #define gate_exists(gate) FLAG_TEST(gate, GATE, EXISTS)
0047 #define gate_is_enabled(gate) FLAG_TEST(gate, GATE, ENABLED)
0048 #define gate_is_hw_controllable(gate) FLAG_TEST(gate, GATE, HW)
0049 #define gate_is_sw_controllable(gate) FLAG_TEST(gate, GATE, SW)
0050 #define gate_is_sw_managed(gate) FLAG_TEST(gate, GATE, SW_MANAGED)
0051 #define gate_is_no_disable(gate) FLAG_TEST(gate, GATE, NO_DISABLE)
0052
0053 #define gate_flip_enabled(gate) FLAG_FLIP(gate, GATE, ENABLED)
0054
0055 #define hyst_exists(hyst) ((hyst)->offset != 0)
0056
0057 #define divider_exists(div) FLAG_TEST(div, DIV, EXISTS)
0058 #define divider_is_fixed(div) FLAG_TEST(div, DIV, FIXED)
0059 #define divider_has_fraction(div) (!divider_is_fixed(div) && \
0060 (div)->u.s.frac_width > 0)
0061
0062 #define selector_exists(sel) ((sel)->width != 0)
0063 #define trigger_exists(trig) FLAG_TEST(trig, TRIG, EXISTS)
0064
0065 #define policy_lvm_en_exists(enable) ((enable)->offset != 0)
0066 #define policy_ctl_exists(control) ((control)->offset != 0)
0067
0068
0069 enum bcm_clk_type {
0070 bcm_clk_none,
0071 bcm_clk_bus,
0072 bcm_clk_core,
0073 bcm_clk_peri
0074 };
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 struct bcm_clk_policy {
0085 u32 offset;
0086 u32 bit;
0087 };
0088
0089
0090
0091 #define POLICY(_offset, _bit) \
0092 { \
0093 .offset = (_offset), \
0094 .bit = (_bit), \
0095 }
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 struct bcm_clk_gate {
0122 u32 offset;
0123 u32 status_bit;
0124 u32 en_bit;
0125 u32 hw_sw_sel_bit;
0126 u32 flags;
0127 };
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137 #define BCM_CLK_GATE_FLAGS_EXISTS ((u32)1 << 0)
0138 #define BCM_CLK_GATE_FLAGS_HW ((u32)1 << 1)
0139 #define BCM_CLK_GATE_FLAGS_SW ((u32)1 << 2)
0140 #define BCM_CLK_GATE_FLAGS_NO_DISABLE ((u32)1 << 3)
0141 #define BCM_CLK_GATE_FLAGS_SW_MANAGED ((u32)1 << 4)
0142 #define BCM_CLK_GATE_FLAGS_ENABLED ((u32)1 << 5)
0143
0144
0145
0146
0147
0148
0149
0150
0151 #define HW_SW_GATE(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \
0152 { \
0153 .offset = (_offset), \
0154 .status_bit = (_status_bit), \
0155 .en_bit = (_en_bit), \
0156 .hw_sw_sel_bit = (_hw_sw_sel_bit), \
0157 .flags = FLAG(GATE, HW)|FLAG(GATE, SW)| \
0158 FLAG(GATE, SW_MANAGED)|FLAG(GATE, ENABLED)| \
0159 FLAG(GATE, EXISTS), \
0160 }
0161
0162
0163 #define HW_SW_GATE_AUTO(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \
0164 { \
0165 .offset = (_offset), \
0166 .status_bit = (_status_bit), \
0167 .en_bit = (_en_bit), \
0168 .hw_sw_sel_bit = (_hw_sw_sel_bit), \
0169 .flags = FLAG(GATE, HW)|FLAG(GATE, SW)| \
0170 FLAG(GATE, EXISTS), \
0171 }
0172
0173
0174 #define HW_ENABLE_GATE(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \
0175 { \
0176 .offset = (_offset), \
0177 .status_bit = (_status_bit), \
0178 .en_bit = (_en_bit), \
0179 .hw_sw_sel_bit = (_hw_sw_sel_bit), \
0180 .flags = FLAG(GATE, HW)|FLAG(GATE, SW)| \
0181 FLAG(GATE, NO_DISABLE)|FLAG(GATE, EXISTS), \
0182 }
0183
0184
0185 #define SW_ONLY_GATE(_offset, _status_bit, _en_bit) \
0186 { \
0187 .offset = (_offset), \
0188 .status_bit = (_status_bit), \
0189 .en_bit = (_en_bit), \
0190 .flags = FLAG(GATE, SW)|FLAG(GATE, SW_MANAGED)| \
0191 FLAG(GATE, ENABLED)|FLAG(GATE, EXISTS), \
0192 }
0193
0194
0195 #define HW_ONLY_GATE(_offset, _status_bit) \
0196 { \
0197 .offset = (_offset), \
0198 .status_bit = (_status_bit), \
0199 .flags = FLAG(GATE, HW)|FLAG(GATE, EXISTS), \
0200 }
0201
0202
0203 struct bcm_clk_hyst {
0204 u32 offset;
0205 u32 en_bit;
0206 u32 val_bit;
0207 };
0208
0209
0210
0211 #define HYST(_offset, _en_bit, _val_bit) \
0212 { \
0213 .offset = (_offset), \
0214 .en_bit = (_en_bit), \
0215 .val_bit = (_val_bit), \
0216 }
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258 struct bcm_clk_div {
0259 union {
0260 struct {
0261 u32 offset;
0262 u32 shift;
0263 u32 width;
0264 u32 frac_width;
0265
0266 u64 scaled_div;
0267 } s;
0268 u32 fixed;
0269 } u;
0270 u32 flags;
0271 };
0272
0273
0274
0275
0276
0277
0278 #define BCM_CLK_DIV_FLAGS_EXISTS ((u32)1 << 0)
0279 #define BCM_CLK_DIV_FLAGS_FIXED ((u32)1 << 1)
0280
0281
0282
0283
0284 #define FIXED_DIVIDER(_value) \
0285 { \
0286 .u.fixed = (_value), \
0287 .flags = FLAG(DIV, EXISTS)|FLAG(DIV, FIXED), \
0288 }
0289
0290
0291 #define DIVIDER(_offset, _shift, _width) \
0292 { \
0293 .u.s.offset = (_offset), \
0294 .u.s.shift = (_shift), \
0295 .u.s.width = (_width), \
0296 .u.s.scaled_div = BAD_SCALED_DIV_VALUE, \
0297 .flags = FLAG(DIV, EXISTS), \
0298 }
0299
0300
0301 #define FRAC_DIVIDER(_offset, _shift, _width, _frac_width) \
0302 { \
0303 .u.s.offset = (_offset), \
0304 .u.s.shift = (_shift), \
0305 .u.s.width = (_width), \
0306 .u.s.frac_width = (_frac_width), \
0307 .u.s.scaled_div = BAD_SCALED_DIV_VALUE, \
0308 .flags = FLAG(DIV, EXISTS), \
0309 }
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331 struct bcm_clk_sel {
0332 u32 offset;
0333 u32 shift;
0334 u32 width;
0335
0336 u32 parent_count;
0337 u32 *parent_sel;
0338 u8 clk_index;
0339 };
0340
0341
0342 #define SELECTOR(_offset, _shift, _width) \
0343 { \
0344 .offset = (_offset), \
0345 .shift = (_shift), \
0346 .width = (_width), \
0347 .clk_index = BAD_CLK_INDEX, \
0348 }
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362 struct bcm_clk_trig {
0363 u32 offset;
0364 u32 bit;
0365 u32 flags;
0366 };
0367
0368
0369
0370
0371
0372 #define BCM_CLK_TRIG_FLAGS_EXISTS ((u32)1 << 0)
0373
0374
0375 #define TRIGGER(_offset, _bit) \
0376 { \
0377 .offset = (_offset), \
0378 .bit = (_bit), \
0379 .flags = FLAG(TRIG, EXISTS), \
0380 }
0381
0382 struct peri_clk_data {
0383 struct bcm_clk_policy policy;
0384 struct bcm_clk_gate gate;
0385 struct bcm_clk_hyst hyst;
0386 struct bcm_clk_trig pre_trig;
0387 struct bcm_clk_div pre_div;
0388 struct bcm_clk_trig trig;
0389 struct bcm_clk_div div;
0390 struct bcm_clk_sel sel;
0391 const char *clocks[];
0392 };
0393 #define CLOCKS(...) { __VA_ARGS__, NULL, }
0394 #define NO_CLOCKS { NULL, }
0395
0396 struct kona_clk {
0397 struct clk_hw hw;
0398 struct clk_init_data init_data;
0399 struct ccu_data *ccu;
0400 enum bcm_clk_type type;
0401 union {
0402 void *data;
0403 struct peri_clk_data *peri;
0404 } u;
0405 };
0406 #define to_kona_clk(_hw) \
0407 container_of(_hw, struct kona_clk, hw)
0408
0409
0410 #define KONA_CLK(_ccu_name, _clk_name, _type) \
0411 { \
0412 .init_data = { \
0413 .name = #_clk_name, \
0414 .ops = &kona_ ## _type ## _clk_ops, \
0415 }, \
0416 .ccu = &_ccu_name ## _ccu_data, \
0417 .type = bcm_clk_ ## _type, \
0418 .u.data = &_clk_name ## _data, \
0419 }
0420 #define LAST_KONA_CLK { .type = bcm_clk_none }
0421
0422
0423
0424
0425
0426
0427
0428 struct bcm_lvm_en {
0429 u32 offset;
0430 u32 bit;
0431 };
0432
0433
0434 #define CCU_LVM_EN(_offset, _bit) \
0435 { \
0436 .offset = (_offset), \
0437 .bit = (_bit), \
0438 }
0439
0440 struct bcm_policy_ctl {
0441 u32 offset;
0442 u32 go_bit;
0443 u32 atl_bit;
0444 u32 ac_bit;
0445 };
0446
0447
0448 #define CCU_POLICY_CTL(_offset, _go_bit, _ac_bit, _atl_bit) \
0449 { \
0450 .offset = (_offset), \
0451 .go_bit = (_go_bit), \
0452 .ac_bit = (_ac_bit), \
0453 .atl_bit = (_atl_bit), \
0454 }
0455
0456 struct ccu_policy {
0457 struct bcm_lvm_en enable;
0458 struct bcm_policy_ctl control;
0459 };
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470 struct ccu_data {
0471 void __iomem *base;
0472 spinlock_t lock;
0473 bool write_enabled;
0474 struct ccu_policy policy;
0475 struct device_node *node;
0476 size_t clk_num;
0477 const char *name;
0478 u32 range;
0479 struct kona_clk kona_clks[];
0480 };
0481
0482
0483 #define KONA_CCU_COMMON(_prefix, _name, _ccuname) \
0484 .name = #_name "_ccu", \
0485 .lock = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock), \
0486 .clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT
0487
0488
0489
0490 extern struct clk_ops kona_peri_clk_ops;
0491
0492
0493
0494 extern u64 scaled_div_max(struct bcm_clk_div *div);
0495 extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value,
0496 u32 billionths);
0497
0498 extern void __init kona_dt_ccu_setup(struct ccu_data *ccu,
0499 struct device_node *node);
0500 extern bool __init kona_ccu_init(struct ccu_data *ccu);
0501
0502 #endif