0001
0002
0003
0004
0005
0006
0007 #include <linux/bitfield.h>
0008 #include <linux/bitops.h>
0009 #include <linux/clk.h>
0010 #include <linux/clk-provider.h>
0011 #include <linux/clockchips.h>
0012 #include <linux/clocksource.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/mfd/syscon.h>
0015 #include <linux/of_address.h>
0016 #include <linux/of_irq.h>
0017 #include <linux/sched_clock.h>
0018 #include <linux/slab.h>
0019 #include <linux/syscore_ops.h>
0020
0021 #include <dt-bindings/clock/ingenic,sysost.h>
0022
0023
0024 #define OST_REG_OSTCCR 0x00
0025 #define OST_REG_OSTCR 0x08
0026 #define OST_REG_OSTFR 0x0c
0027 #define OST_REG_OSTMR 0x10
0028 #define OST_REG_OST1DFR 0x14
0029 #define OST_REG_OST1CNT 0x18
0030 #define OST_REG_OST2CNTL 0x20
0031 #define OST_REG_OSTCNT2HBUF 0x24
0032 #define OST_REG_OSTESR 0x34
0033 #define OST_REG_OSTECR 0x38
0034
0035
0036 #define OSTCCR_PRESCALE1_MASK 0x3
0037 #define OSTCCR_PRESCALE2_MASK 0xc
0038
0039
0040 #define OSTCR_OST1CLR BIT(0)
0041 #define OSTCR_OST2CLR BIT(1)
0042
0043
0044 #define OSTFR_FFLAG BIT(0)
0045
0046
0047 #define OSTMR_FMASK BIT(0)
0048
0049
0050 #define OSTESR_OST1ENS BIT(0)
0051 #define OSTESR_OST2ENS BIT(1)
0052
0053
0054 #define OSTECR_OST1ENC BIT(0)
0055 #define OSTECR_OST2ENC BIT(1)
0056
0057 struct ingenic_soc_info {
0058 unsigned int num_channels;
0059 };
0060
0061 struct ingenic_ost_clk_info {
0062 struct clk_init_data init_data;
0063 u8 ostccr_reg;
0064 };
0065
0066 struct ingenic_ost_clk {
0067 struct clk_hw hw;
0068 unsigned int idx;
0069 struct ingenic_ost *ost;
0070 const struct ingenic_ost_clk_info *info;
0071 };
0072
0073 struct ingenic_ost {
0074 void __iomem *base;
0075 const struct ingenic_soc_info *soc_info;
0076 struct clk *clk, *percpu_timer_clk, *global_timer_clk;
0077 struct clock_event_device cevt;
0078 struct clocksource cs;
0079 char name[20];
0080
0081 struct clk_hw_onecell_data *clocks;
0082 };
0083
0084 static struct ingenic_ost *ingenic_ost;
0085
0086 static inline struct ingenic_ost_clk *to_ost_clk(struct clk_hw *hw)
0087 {
0088 return container_of(hw, struct ingenic_ost_clk, hw);
0089 }
0090
0091 static unsigned long ingenic_ost_percpu_timer_recalc_rate(struct clk_hw *hw,
0092 unsigned long parent_rate)
0093 {
0094 struct ingenic_ost_clk *ost_clk = to_ost_clk(hw);
0095 const struct ingenic_ost_clk_info *info = ost_clk->info;
0096 unsigned int prescale;
0097
0098 prescale = readl(ost_clk->ost->base + info->ostccr_reg);
0099
0100 prescale = FIELD_GET(OSTCCR_PRESCALE1_MASK, prescale);
0101
0102 return parent_rate >> (prescale * 2);
0103 }
0104
0105 static unsigned long ingenic_ost_global_timer_recalc_rate(struct clk_hw *hw,
0106 unsigned long parent_rate)
0107 {
0108 struct ingenic_ost_clk *ost_clk = to_ost_clk(hw);
0109 const struct ingenic_ost_clk_info *info = ost_clk->info;
0110 unsigned int prescale;
0111
0112 prescale = readl(ost_clk->ost->base + info->ostccr_reg);
0113
0114 prescale = FIELD_GET(OSTCCR_PRESCALE2_MASK, prescale);
0115
0116 return parent_rate >> (prescale * 2);
0117 }
0118
0119 static u8 ingenic_ost_get_prescale(unsigned long rate, unsigned long req_rate)
0120 {
0121 u8 prescale;
0122
0123 for (prescale = 0; prescale < 2; prescale++)
0124 if ((rate >> (prescale * 2)) <= req_rate)
0125 return prescale;
0126
0127 return 2;
0128 }
0129
0130 static long ingenic_ost_round_rate(struct clk_hw *hw, unsigned long req_rate,
0131 unsigned long *parent_rate)
0132 {
0133 unsigned long rate = *parent_rate;
0134 u8 prescale;
0135
0136 if (req_rate > rate)
0137 return rate;
0138
0139 prescale = ingenic_ost_get_prescale(rate, req_rate);
0140
0141 return rate >> (prescale * 2);
0142 }
0143
0144 static int ingenic_ost_percpu_timer_set_rate(struct clk_hw *hw, unsigned long req_rate,
0145 unsigned long parent_rate)
0146 {
0147 struct ingenic_ost_clk *ost_clk = to_ost_clk(hw);
0148 const struct ingenic_ost_clk_info *info = ost_clk->info;
0149 u8 prescale = ingenic_ost_get_prescale(parent_rate, req_rate);
0150 int val;
0151
0152 val = readl(ost_clk->ost->base + info->ostccr_reg);
0153 val &= ~OSTCCR_PRESCALE1_MASK;
0154 val |= FIELD_PREP(OSTCCR_PRESCALE1_MASK, prescale);
0155 writel(val, ost_clk->ost->base + info->ostccr_reg);
0156
0157 return 0;
0158 }
0159
0160 static int ingenic_ost_global_timer_set_rate(struct clk_hw *hw, unsigned long req_rate,
0161 unsigned long parent_rate)
0162 {
0163 struct ingenic_ost_clk *ost_clk = to_ost_clk(hw);
0164 const struct ingenic_ost_clk_info *info = ost_clk->info;
0165 u8 prescale = ingenic_ost_get_prescale(parent_rate, req_rate);
0166 int val;
0167
0168 val = readl(ost_clk->ost->base + info->ostccr_reg);
0169 val &= ~OSTCCR_PRESCALE2_MASK;
0170 val |= FIELD_PREP(OSTCCR_PRESCALE2_MASK, prescale);
0171 writel(val, ost_clk->ost->base + info->ostccr_reg);
0172
0173 return 0;
0174 }
0175
0176 static const struct clk_ops ingenic_ost_percpu_timer_ops = {
0177 .recalc_rate = ingenic_ost_percpu_timer_recalc_rate,
0178 .round_rate = ingenic_ost_round_rate,
0179 .set_rate = ingenic_ost_percpu_timer_set_rate,
0180 };
0181
0182 static const struct clk_ops ingenic_ost_global_timer_ops = {
0183 .recalc_rate = ingenic_ost_global_timer_recalc_rate,
0184 .round_rate = ingenic_ost_round_rate,
0185 .set_rate = ingenic_ost_global_timer_set_rate,
0186 };
0187
0188 static const char * const ingenic_ost_clk_parents[] = { "ext" };
0189
0190 static const struct ingenic_ost_clk_info x1000_ost_clk_info[] = {
0191 [OST_CLK_PERCPU_TIMER] = {
0192 .init_data = {
0193 .name = "percpu timer",
0194 .parent_names = ingenic_ost_clk_parents,
0195 .num_parents = ARRAY_SIZE(ingenic_ost_clk_parents),
0196 .ops = &ingenic_ost_percpu_timer_ops,
0197 .flags = CLK_SET_RATE_UNGATE,
0198 },
0199 .ostccr_reg = OST_REG_OSTCCR,
0200 },
0201
0202 [OST_CLK_GLOBAL_TIMER] = {
0203 .init_data = {
0204 .name = "global timer",
0205 .parent_names = ingenic_ost_clk_parents,
0206 .num_parents = ARRAY_SIZE(ingenic_ost_clk_parents),
0207 .ops = &ingenic_ost_global_timer_ops,
0208 .flags = CLK_SET_RATE_UNGATE,
0209 },
0210 .ostccr_reg = OST_REG_OSTCCR,
0211 },
0212 };
0213
0214 static u64 notrace ingenic_ost_global_timer_read_cntl(void)
0215 {
0216 struct ingenic_ost *ost = ingenic_ost;
0217 unsigned int count;
0218
0219 count = readl(ost->base + OST_REG_OST2CNTL);
0220
0221 return count;
0222 }
0223
0224 static u64 notrace ingenic_ost_clocksource_read(struct clocksource *cs)
0225 {
0226 return ingenic_ost_global_timer_read_cntl();
0227 }
0228
0229 static inline struct ingenic_ost *to_ingenic_ost(struct clock_event_device *evt)
0230 {
0231 return container_of(evt, struct ingenic_ost, cevt);
0232 }
0233
0234 static int ingenic_ost_cevt_set_state_shutdown(struct clock_event_device *evt)
0235 {
0236 struct ingenic_ost *ost = to_ingenic_ost(evt);
0237
0238 writel(OSTECR_OST1ENC, ost->base + OST_REG_OSTECR);
0239
0240 return 0;
0241 }
0242
0243 static int ingenic_ost_cevt_set_next(unsigned long next,
0244 struct clock_event_device *evt)
0245 {
0246 struct ingenic_ost *ost = to_ingenic_ost(evt);
0247
0248 writel((u32)~OSTFR_FFLAG, ost->base + OST_REG_OSTFR);
0249 writel(next, ost->base + OST_REG_OST1DFR);
0250 writel(OSTCR_OST1CLR, ost->base + OST_REG_OSTCR);
0251 writel(OSTESR_OST1ENS, ost->base + OST_REG_OSTESR);
0252 writel((u32)~OSTMR_FMASK, ost->base + OST_REG_OSTMR);
0253
0254 return 0;
0255 }
0256
0257 static irqreturn_t ingenic_ost_cevt_cb(int irq, void *dev_id)
0258 {
0259 struct clock_event_device *evt = dev_id;
0260 struct ingenic_ost *ost = to_ingenic_ost(evt);
0261
0262 writel(OSTECR_OST1ENC, ost->base + OST_REG_OSTECR);
0263
0264 if (evt->event_handler)
0265 evt->event_handler(evt);
0266
0267 return IRQ_HANDLED;
0268 }
0269
0270 static int __init ingenic_ost_register_clock(struct ingenic_ost *ost,
0271 unsigned int idx, const struct ingenic_ost_clk_info *info,
0272 struct clk_hw_onecell_data *clocks)
0273 {
0274 struct ingenic_ost_clk *ost_clk;
0275 int val, err;
0276
0277 ost_clk = kzalloc(sizeof(*ost_clk), GFP_KERNEL);
0278 if (!ost_clk)
0279 return -ENOMEM;
0280
0281 ost_clk->hw.init = &info->init_data;
0282 ost_clk->idx = idx;
0283 ost_clk->info = info;
0284 ost_clk->ost = ost;
0285
0286
0287 val = readl(ost->base + info->ostccr_reg);
0288 val &= ~(OSTCCR_PRESCALE1_MASK | OSTCCR_PRESCALE2_MASK);
0289 writel(val, ost->base + info->ostccr_reg);
0290
0291 err = clk_hw_register(NULL, &ost_clk->hw);
0292 if (err) {
0293 kfree(ost_clk);
0294 return err;
0295 }
0296
0297 clocks->hws[idx] = &ost_clk->hw;
0298
0299 return 0;
0300 }
0301
0302 static struct clk * __init ingenic_ost_get_clock(struct device_node *np, int id)
0303 {
0304 struct of_phandle_args args;
0305
0306 args.np = np;
0307 args.args_count = 1;
0308 args.args[0] = id;
0309
0310 return of_clk_get_from_provider(&args);
0311 }
0312
0313 static int __init ingenic_ost_percpu_timer_init(struct device_node *np,
0314 struct ingenic_ost *ost)
0315 {
0316 unsigned int timer_virq, channel = OST_CLK_PERCPU_TIMER;
0317 unsigned long rate;
0318 int err;
0319
0320 ost->percpu_timer_clk = ingenic_ost_get_clock(np, channel);
0321 if (IS_ERR(ost->percpu_timer_clk))
0322 return PTR_ERR(ost->percpu_timer_clk);
0323
0324 err = clk_prepare_enable(ost->percpu_timer_clk);
0325 if (err)
0326 goto err_clk_put;
0327
0328 rate = clk_get_rate(ost->percpu_timer_clk);
0329 if (!rate) {
0330 err = -EINVAL;
0331 goto err_clk_disable;
0332 }
0333
0334 timer_virq = of_irq_get(np, 0);
0335 if (!timer_virq) {
0336 err = -EINVAL;
0337 goto err_clk_disable;
0338 }
0339
0340 snprintf(ost->name, sizeof(ost->name), "OST percpu timer");
0341
0342 err = request_irq(timer_virq, ingenic_ost_cevt_cb, IRQF_TIMER,
0343 ost->name, &ost->cevt);
0344 if (err)
0345 goto err_irq_dispose_mapping;
0346
0347 ost->cevt.cpumask = cpumask_of(smp_processor_id());
0348 ost->cevt.features = CLOCK_EVT_FEAT_ONESHOT;
0349 ost->cevt.name = ost->name;
0350 ost->cevt.rating = 400;
0351 ost->cevt.set_state_shutdown = ingenic_ost_cevt_set_state_shutdown;
0352 ost->cevt.set_next_event = ingenic_ost_cevt_set_next;
0353
0354 clockevents_config_and_register(&ost->cevt, rate, 4, 0xffffffff);
0355
0356 return 0;
0357
0358 err_irq_dispose_mapping:
0359 irq_dispose_mapping(timer_virq);
0360 err_clk_disable:
0361 clk_disable_unprepare(ost->percpu_timer_clk);
0362 err_clk_put:
0363 clk_put(ost->percpu_timer_clk);
0364 return err;
0365 }
0366
0367 static int __init ingenic_ost_global_timer_init(struct device_node *np,
0368 struct ingenic_ost *ost)
0369 {
0370 unsigned int channel = OST_CLK_GLOBAL_TIMER;
0371 struct clocksource *cs = &ost->cs;
0372 unsigned long rate;
0373 int err;
0374
0375 ost->global_timer_clk = ingenic_ost_get_clock(np, channel);
0376 if (IS_ERR(ost->global_timer_clk))
0377 return PTR_ERR(ost->global_timer_clk);
0378
0379 err = clk_prepare_enable(ost->global_timer_clk);
0380 if (err)
0381 goto err_clk_put;
0382
0383 rate = clk_get_rate(ost->global_timer_clk);
0384 if (!rate) {
0385 err = -EINVAL;
0386 goto err_clk_disable;
0387 }
0388
0389
0390 writel(OSTCR_OST2CLR, ost->base + OST_REG_OSTCR);
0391
0392
0393 writel(OSTESR_OST2ENS, ost->base + OST_REG_OSTESR);
0394
0395 cs->name = "ingenic-ost";
0396 cs->rating = 400;
0397 cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
0398 cs->mask = CLOCKSOURCE_MASK(32);
0399 cs->read = ingenic_ost_clocksource_read;
0400
0401 err = clocksource_register_hz(cs, rate);
0402 if (err)
0403 goto err_clk_disable;
0404
0405 return 0;
0406
0407 err_clk_disable:
0408 clk_disable_unprepare(ost->global_timer_clk);
0409 err_clk_put:
0410 clk_put(ost->global_timer_clk);
0411 return err;
0412 }
0413
0414 static const struct ingenic_soc_info x1000_soc_info = {
0415 .num_channels = 2,
0416 };
0417
0418 static const struct of_device_id __maybe_unused ingenic_ost_of_matches[] __initconst = {
0419 { .compatible = "ingenic,x1000-ost", .data = &x1000_soc_info },
0420 { }
0421 };
0422
0423 static int __init ingenic_ost_probe(struct device_node *np)
0424 {
0425 const struct of_device_id *id = of_match_node(ingenic_ost_of_matches, np);
0426 struct ingenic_ost *ost;
0427 unsigned int i;
0428 int ret;
0429
0430 ost = kzalloc(sizeof(*ost), GFP_KERNEL);
0431 if (!ost)
0432 return -ENOMEM;
0433
0434 ost->base = of_io_request_and_map(np, 0, of_node_full_name(np));
0435 if (IS_ERR(ost->base)) {
0436 pr_err("%s: Failed to map OST registers\n", __func__);
0437 ret = PTR_ERR(ost->base);
0438 goto err_free_ost;
0439 }
0440
0441 ost->clk = of_clk_get_by_name(np, "ost");
0442 if (IS_ERR(ost->clk)) {
0443 ret = PTR_ERR(ost->clk);
0444 pr_crit("%s: Cannot get OST clock\n", __func__);
0445 goto err_free_ost;
0446 }
0447
0448 ret = clk_prepare_enable(ost->clk);
0449 if (ret) {
0450 pr_crit("%s: Unable to enable OST clock\n", __func__);
0451 goto err_put_clk;
0452 }
0453
0454 ost->soc_info = id->data;
0455
0456 ost->clocks = kzalloc(struct_size(ost->clocks, hws, ost->soc_info->num_channels),
0457 GFP_KERNEL);
0458 if (!ost->clocks) {
0459 ret = -ENOMEM;
0460 goto err_clk_disable;
0461 }
0462
0463 ost->clocks->num = ost->soc_info->num_channels;
0464
0465 for (i = 0; i < ost->clocks->num; i++) {
0466 ret = ingenic_ost_register_clock(ost, i, &x1000_ost_clk_info[i], ost->clocks);
0467 if (ret) {
0468 pr_crit("%s: Cannot register clock %d\n", __func__, i);
0469 goto err_unregister_ost_clocks;
0470 }
0471 }
0472
0473 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, ost->clocks);
0474 if (ret) {
0475 pr_crit("%s: Cannot add OF clock provider\n", __func__);
0476 goto err_unregister_ost_clocks;
0477 }
0478
0479 ingenic_ost = ost;
0480
0481 return 0;
0482
0483 err_unregister_ost_clocks:
0484 for (i = 0; i < ost->clocks->num; i++)
0485 if (ost->clocks->hws[i])
0486 clk_hw_unregister(ost->clocks->hws[i]);
0487 kfree(ost->clocks);
0488 err_clk_disable:
0489 clk_disable_unprepare(ost->clk);
0490 err_put_clk:
0491 clk_put(ost->clk);
0492 err_free_ost:
0493 kfree(ost);
0494 return ret;
0495 }
0496
0497 static int __init ingenic_ost_init(struct device_node *np)
0498 {
0499 struct ingenic_ost *ost;
0500 unsigned long rate;
0501 int ret;
0502
0503 ret = ingenic_ost_probe(np);
0504 if (ret) {
0505 pr_crit("%s: Failed to initialize OST clocks: %d\n", __func__, ret);
0506 return ret;
0507 }
0508
0509 of_node_clear_flag(np, OF_POPULATED);
0510
0511 ost = ingenic_ost;
0512 if (IS_ERR(ost))
0513 return PTR_ERR(ost);
0514
0515 ret = ingenic_ost_global_timer_init(np, ost);
0516 if (ret) {
0517 pr_crit("%s: Unable to init global timer: %x\n", __func__, ret);
0518 goto err_free_ingenic_ost;
0519 }
0520
0521 ret = ingenic_ost_percpu_timer_init(np, ost);
0522 if (ret)
0523 goto err_ost_global_timer_cleanup;
0524
0525
0526 rate = clk_get_rate(ost->global_timer_clk);
0527 sched_clock_register(ingenic_ost_global_timer_read_cntl, 32, rate);
0528
0529 return 0;
0530
0531 err_ost_global_timer_cleanup:
0532 clocksource_unregister(&ost->cs);
0533 clk_disable_unprepare(ost->global_timer_clk);
0534 clk_put(ost->global_timer_clk);
0535 err_free_ingenic_ost:
0536 kfree(ost);
0537 return ret;
0538 }
0539
0540 TIMER_OF_DECLARE(x1000_ost, "ingenic,x1000-ost", ingenic_ost_init);