aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/keystone/sci-clk.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/keystone/sci-clk.c')
-rw-r--r--drivers/clk/keystone/sci-clk.c380
1 files changed, 90 insertions, 290 deletions
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
index 9cdf9d5050ac..4cb70bed89a9 100644
--- a/drivers/clk/keystone/sci-clk.c
+++ b/drivers/clk/keystone/sci-clk.c
@@ -29,21 +29,10 @@
29#define SCI_CLK_INPUT_TERMINATION BIT(2) 29#define SCI_CLK_INPUT_TERMINATION BIT(2)
30 30
31/** 31/**
32 * struct sci_clk_data - TI SCI clock data
33 * @dev: device index
34 * @num_clks: number of clocks for this device
35 */
36struct sci_clk_data {
37 u16 dev;
38 u16 num_clks;
39};
40
41/**
42 * struct sci_clk_provider - TI SCI clock provider representation 32 * struct sci_clk_provider - TI SCI clock provider representation
43 * @sci: Handle to the System Control Interface protocol handler 33 * @sci: Handle to the System Control Interface protocol handler
44 * @ops: Pointer to the SCI ops to be used by the clocks 34 * @ops: Pointer to the SCI ops to be used by the clocks
45 * @dev: Device pointer for the clock provider 35 * @dev: Device pointer for the clock provider
46 * @clk_data: Clock data
47 * @clocks: Clocks array for this device 36 * @clocks: Clocks array for this device
48 * @num_clocks: Total number of clocks for this provider 37 * @num_clocks: Total number of clocks for this provider
49 */ 38 */
@@ -51,8 +40,7 @@ struct sci_clk_provider {
51 const struct ti_sci_handle *sci; 40 const struct ti_sci_handle *sci;
52 const struct ti_sci_clk_ops *ops; 41 const struct ti_sci_clk_ops *ops;
53 struct device *dev; 42 struct device *dev;
54 const struct sci_clk_data *clk_data; 43 struct sci_clk **clocks;
55 struct clk_hw **clocks;
56 int num_clocks; 44 int num_clocks;
57}; 45};
58 46
@@ -61,6 +49,7 @@ struct sci_clk_provider {
61 * @hw: Hardware clock cookie for common clock framework 49 * @hw: Hardware clock cookie for common clock framework
62 * @dev_id: Device index 50 * @dev_id: Device index
63 * @clk_id: Clock index 51 * @clk_id: Clock index
52 * @num_parents: Number of parents for this clock
64 * @provider: Master clock provider 53 * @provider: Master clock provider
65 * @flags: Flags for the clock 54 * @flags: Flags for the clock
66 */ 55 */
@@ -68,6 +57,7 @@ struct sci_clk {
68 struct clk_hw hw; 57 struct clk_hw hw;
69 u16 dev_id; 58 u16 dev_id;
70 u8 clk_id; 59 u8 clk_id;
60 u8 num_parents;
71 struct sci_clk_provider *provider; 61 struct sci_clk_provider *provider;
72 u8 flags; 62 u8 flags;
73}; 63};
@@ -273,38 +263,22 @@ static const struct clk_ops sci_clk_ops = {
273/** 263/**
274 * _sci_clk_get - Gets a handle for an SCI clock 264 * _sci_clk_get - Gets a handle for an SCI clock
275 * @provider: Handle to SCI clock provider 265 * @provider: Handle to SCI clock provider
276 * @dev_id: device ID for the clock to register 266 * @sci_clk: Handle to the SCI clock to populate
277 * @clk_id: clock ID for the clock to register
278 * 267 *
279 * Gets a handle to an existing TI SCI hw clock, or builds a new clock 268 * Gets a handle to an existing TI SCI hw clock, or builds a new clock
280 * entry and registers it with the common clock framework. Called from 269 * entry and registers it with the common clock framework. Called from
281 * the common clock framework, when a corresponding of_clk_get call is 270 * the common clock framework, when a corresponding of_clk_get call is
282 * executed, or recursively from itself when parsing parent clocks. 271 * executed, or recursively from itself when parsing parent clocks.
283 * Returns a pointer to the hw clock struct, or ERR_PTR value in failure. 272 * Returns 0 on success, negative error code on failure.
284 */ 273 */
285static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider, 274static int _sci_clk_build(struct sci_clk_provider *provider,
286 u16 dev_id, u8 clk_id) 275 struct sci_clk *sci_clk)
287{ 276{
288 struct clk_init_data init = { NULL }; 277 struct clk_init_data init = { NULL };
289 struct sci_clk *sci_clk = NULL;
290 char *name = NULL; 278 char *name = NULL;
291 char **parent_names = NULL; 279 char **parent_names = NULL;
292 int i; 280 int i;
293 int ret; 281 int ret = 0;
294
295 sci_clk = devm_kzalloc(provider->dev, sizeof(*sci_clk), GFP_KERNEL);
296 if (!sci_clk)
297 return ERR_PTR(-ENOMEM);
298
299 sci_clk->dev_id = dev_id;
300 sci_clk->clk_id = clk_id;
301 sci_clk->provider = provider;
302
303 ret = provider->ops->get_num_parents(provider->sci, dev_id,
304 clk_id,
305 &init.num_parents);
306 if (ret)
307 goto err;
308 282
309 name = kasprintf(GFP_KERNEL, "%s:%d:%d", dev_name(provider->dev), 283 name = kasprintf(GFP_KERNEL, "%s:%d:%d", dev_name(provider->dev),
310 sci_clk->dev_id, sci_clk->clk_id); 284 sci_clk->dev_id, sci_clk->clk_id);
@@ -317,11 +291,11 @@ static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider,
317 * to have mux functionality. Otherwise it is going to act as a root 291 * to have mux functionality. Otherwise it is going to act as a root
318 * clock. 292 * clock.
319 */ 293 */
320 if (init.num_parents < 2) 294 if (sci_clk->num_parents < 2)
321 init.num_parents = 0; 295 sci_clk->num_parents = 0;
322 296
323 if (init.num_parents) { 297 if (sci_clk->num_parents) {
324 parent_names = kcalloc(init.num_parents, sizeof(char *), 298 parent_names = kcalloc(sci_clk->num_parents, sizeof(char *),
325 GFP_KERNEL); 299 GFP_KERNEL);
326 300
327 if (!parent_names) { 301 if (!parent_names) {
@@ -329,7 +303,7 @@ static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider,
329 goto err; 303 goto err;
330 } 304 }
331 305
332 for (i = 0; i < init.num_parents; i++) { 306 for (i = 0; i < sci_clk->num_parents; i++) {
333 char *parent_name; 307 char *parent_name;
334 308
335 parent_name = kasprintf(GFP_KERNEL, "%s:%d:%d", 309 parent_name = kasprintf(GFP_KERNEL, "%s:%d:%d",
@@ -346,6 +320,7 @@ static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider,
346 } 320 }
347 321
348 init.ops = &sci_clk_ops; 322 init.ops = &sci_clk_ops;
323 init.num_parents = sci_clk->num_parents;
349 sci_clk->hw.init = &init; 324 sci_clk->hw.init = &init;
350 325
351 ret = devm_clk_hw_register(provider->dev, &sci_clk->hw); 326 ret = devm_clk_hw_register(provider->dev, &sci_clk->hw);
@@ -354,7 +329,7 @@ static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider,
354 329
355err: 330err:
356 if (parent_names) { 331 if (parent_names) {
357 for (i = 0; i < init.num_parents; i++) 332 for (i = 0; i < sci_clk->num_parents; i++)
358 kfree(parent_names[i]); 333 kfree(parent_names[i]);
359 334
360 kfree(parent_names); 335 kfree(parent_names);
@@ -362,10 +337,7 @@ err:
362 337
363 kfree(name); 338 kfree(name);
364 339
365 if (ret) 340 return ret;
366 return ERR_PTR(ret);
367
368 return &sci_clk->hw;
369} 341}
370 342
371static int _cmp_sci_clk(const void *a, const void *b) 343static int _cmp_sci_clk(const void *a, const void *b)
@@ -414,253 +386,20 @@ static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data)
414 386
415static int ti_sci_init_clocks(struct sci_clk_provider *p) 387static int ti_sci_init_clocks(struct sci_clk_provider *p)
416{ 388{
417 const struct sci_clk_data *data = p->clk_data;
418 struct clk_hw *hw;
419 int i; 389 int i;
420 int num_clks = 0; 390 int ret;
421
422 while (data->num_clks) {
423 num_clks += data->num_clks;
424 data++;
425 }
426
427 p->num_clocks = num_clks;
428
429 p->clocks = devm_kcalloc(p->dev, num_clks, sizeof(struct sci_clk),
430 GFP_KERNEL);
431 if (!p->clocks)
432 return -ENOMEM;
433
434 num_clks = 0;
435
436 data = p->clk_data;
437
438 while (data->num_clks) {
439 for (i = 0; i < data->num_clks; i++) {
440 hw = _sci_clk_build(p, data->dev, i);
441 if (!IS_ERR(hw)) {
442 p->clocks[num_clks++] = hw;
443 continue;
444 }
445
446 /* Skip any holes in the clock lists */
447 if (PTR_ERR(hw) == -ENODEV)
448 continue;
449 391
450 return PTR_ERR(hw); 392 for (i = 0; i < p->num_clocks; i++) {
451 } 393 ret = _sci_clk_build(p, p->clocks[i]);
452 data++; 394 if (ret)
395 return ret;
453 } 396 }
454 397
455 return 0; 398 return 0;
456} 399}
457 400
458static const struct sci_clk_data k2g_clk_data[] = {
459 /* pmmc */
460 { .dev = 0x0, .num_clks = 4 },
461
462 /* mlb0 */
463 { .dev = 0x1, .num_clks = 5 },
464
465 /* dss0 */
466 { .dev = 0x2, .num_clks = 2 },
467
468 /* mcbsp0 */
469 { .dev = 0x3, .num_clks = 8 },
470
471 /* mcasp0 */
472 { .dev = 0x4, .num_clks = 8 },
473
474 /* mcasp1 */
475 { .dev = 0x5, .num_clks = 8 },
476
477 /* mcasp2 */
478 { .dev = 0x6, .num_clks = 8 },
479
480 /* dcan0 */
481 { .dev = 0x8, .num_clks = 2 },
482
483 /* dcan1 */
484 { .dev = 0x9, .num_clks = 2 },
485
486 /* emif0 */
487 { .dev = 0xa, .num_clks = 6 },
488
489 /* mmchs0 */
490 { .dev = 0xb, .num_clks = 3 },
491
492 /* mmchs1 */
493 { .dev = 0xc, .num_clks = 3 },
494
495 /* gpmc0 */
496 { .dev = 0xd, .num_clks = 1 },
497
498 /* elm0 */
499 { .dev = 0xe, .num_clks = 1 },
500
501 /* spi0 */
502 { .dev = 0x10, .num_clks = 1 },
503
504 /* spi1 */
505 { .dev = 0x11, .num_clks = 1 },
506
507 /* spi2 */
508 { .dev = 0x12, .num_clks = 1 },
509
510 /* spi3 */
511 { .dev = 0x13, .num_clks = 1 },
512
513 /* icss0 */
514 { .dev = 0x14, .num_clks = 6 },
515
516 /* icss1 */
517 { .dev = 0x15, .num_clks = 6 },
518
519 /* usb0 */
520 { .dev = 0x16, .num_clks = 7 },
521
522 /* usb1 */
523 { .dev = 0x17, .num_clks = 7 },
524
525 /* nss0 */
526 { .dev = 0x18, .num_clks = 14 },
527
528 /* pcie0 */
529 { .dev = 0x19, .num_clks = 1 },
530
531 /* gpio0 */
532 { .dev = 0x1b, .num_clks = 1 },
533
534 /* gpio1 */
535 { .dev = 0x1c, .num_clks = 1 },
536
537 /* timer64_0 */
538 { .dev = 0x1d, .num_clks = 9 },
539
540 /* timer64_1 */
541 { .dev = 0x1e, .num_clks = 9 },
542
543 /* timer64_2 */
544 { .dev = 0x1f, .num_clks = 9 },
545
546 /* timer64_3 */
547 { .dev = 0x20, .num_clks = 9 },
548
549 /* timer64_4 */
550 { .dev = 0x21, .num_clks = 9 },
551
552 /* timer64_5 */
553 { .dev = 0x22, .num_clks = 9 },
554
555 /* timer64_6 */
556 { .dev = 0x23, .num_clks = 9 },
557
558 /* msgmgr0 */
559 { .dev = 0x25, .num_clks = 1 },
560
561 /* bootcfg0 */
562 { .dev = 0x26, .num_clks = 1 },
563
564 /* arm_bootrom0 */
565 { .dev = 0x27, .num_clks = 1 },
566
567 /* dsp_bootrom0 */
568 { .dev = 0x29, .num_clks = 1 },
569
570 /* debugss0 */
571 { .dev = 0x2b, .num_clks = 8 },
572
573 /* uart0 */
574 { .dev = 0x2c, .num_clks = 1 },
575
576 /* uart1 */
577 { .dev = 0x2d, .num_clks = 1 },
578
579 /* uart2 */
580 { .dev = 0x2e, .num_clks = 1 },
581
582 /* ehrpwm0 */
583 { .dev = 0x2f, .num_clks = 1 },
584
585 /* ehrpwm1 */
586 { .dev = 0x30, .num_clks = 1 },
587
588 /* ehrpwm2 */
589 { .dev = 0x31, .num_clks = 1 },
590
591 /* ehrpwm3 */
592 { .dev = 0x32, .num_clks = 1 },
593
594 /* ehrpwm4 */
595 { .dev = 0x33, .num_clks = 1 },
596
597 /* ehrpwm5 */
598 { .dev = 0x34, .num_clks = 1 },
599
600 /* eqep0 */
601 { .dev = 0x35, .num_clks = 1 },
602
603 /* eqep1 */
604 { .dev = 0x36, .num_clks = 1 },
605
606 /* eqep2 */
607 { .dev = 0x37, .num_clks = 1 },
608
609 /* ecap0 */
610 { .dev = 0x38, .num_clks = 1 },
611
612 /* ecap1 */
613 { .dev = 0x39, .num_clks = 1 },
614
615 /* i2c0 */
616 { .dev = 0x3a, .num_clks = 1 },
617
618 /* i2c1 */
619 { .dev = 0x3b, .num_clks = 1 },
620
621 /* i2c2 */
622 { .dev = 0x3c, .num_clks = 1 },
623
624 /* edma0 */
625 { .dev = 0x3f, .num_clks = 2 },
626
627 /* semaphore0 */
628 { .dev = 0x40, .num_clks = 1 },
629
630 /* intc0 */
631 { .dev = 0x41, .num_clks = 1 },
632
633 /* gic0 */
634 { .dev = 0x42, .num_clks = 1 },
635
636 /* qspi0 */
637 { .dev = 0x43, .num_clks = 5 },
638
639 /* arm_64b_counter0 */
640 { .dev = 0x44, .num_clks = 2 },
641
642 /* tetris0 */
643 { .dev = 0x45, .num_clks = 2 },
644
645 /* cgem0 */
646 { .dev = 0x46, .num_clks = 2 },
647
648 /* msmc0 */
649 { .dev = 0x47, .num_clks = 1 },
650
651 /* cbass0 */
652 { .dev = 0x49, .num_clks = 1 },
653
654 /* board0 */
655 { .dev = 0x4c, .num_clks = 36 },
656
657 /* edma1 */
658 { .dev = 0x4f, .num_clks = 2 },
659 { .num_clks = 0 },
660};
661
662static const struct of_device_id ti_sci_clk_of_match[] = { 401static const struct of_device_id ti_sci_clk_of_match[] = {
663 { .compatible = "ti,k2g-sci-clk", .data = &k2g_clk_data }, 402 { .compatible = "ti,k2g-sci-clk" },
664 { /* Sentinel */ }, 403 { /* Sentinel */ },
665}; 404};
666MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match); 405MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match);
@@ -681,12 +420,16 @@ static int ti_sci_clk_probe(struct platform_device *pdev)
681 struct device_node *np = dev->of_node; 420 struct device_node *np = dev->of_node;
682 struct sci_clk_provider *provider; 421 struct sci_clk_provider *provider;
683 const struct ti_sci_handle *handle; 422 const struct ti_sci_handle *handle;
684 const struct sci_clk_data *data;
685 int ret; 423 int ret;
686 424 int num_clks = 0;
687 data = of_device_get_match_data(dev); 425 struct sci_clk **clks = NULL;
688 if (!data) 426 struct sci_clk **tmp_clks;
689 return -EINVAL; 427 struct sci_clk *sci_clk;
428 int max_clks = 0;
429 int clk_id = 0;
430 int dev_id = 0;
431 u8 num_parents;
432 int gap_size = 0;
690 433
691 handle = devm_ti_sci_get_handle(dev); 434 handle = devm_ti_sci_get_handle(dev);
692 if (IS_ERR(handle)) 435 if (IS_ERR(handle))
@@ -696,12 +439,69 @@ static int ti_sci_clk_probe(struct platform_device *pdev)
696 if (!provider) 439 if (!provider)
697 return -ENOMEM; 440 return -ENOMEM;
698 441
699 provider->clk_data = data;
700
701 provider->sci = handle; 442 provider->sci = handle;
702 provider->ops = &handle->ops.clk_ops; 443 provider->ops = &handle->ops.clk_ops;
703 provider->dev = dev; 444 provider->dev = dev;
704 445
446 while (1) {
447 ret = provider->ops->get_num_parents(provider->sci, dev_id,
448 clk_id, &num_parents);
449 if (ret) {
450 gap_size++;
451 if (!clk_id) {
452 if (gap_size >= 5)
453 break;
454 dev_id++;
455 } else {
456 if (gap_size >= 2) {
457 dev_id++;
458 clk_id = 0;
459 gap_size = 0;
460 } else {
461 clk_id++;
462 }
463 }
464 continue;
465 }
466
467 gap_size = 0;
468
469 if (num_clks == max_clks) {
470 tmp_clks = devm_kmalloc_array(dev, max_clks + 64,
471 sizeof(sci_clk),
472 GFP_KERNEL);
473 memcpy(tmp_clks, clks, max_clks * sizeof(sci_clk));
474 if (max_clks)
475 devm_kfree(dev, clks);
476 max_clks += 64;
477 clks = tmp_clks;
478 }
479
480 sci_clk = devm_kzalloc(dev, sizeof(*sci_clk), GFP_KERNEL);
481 if (!sci_clk)
482 return -ENOMEM;
483 sci_clk->dev_id = dev_id;
484 sci_clk->clk_id = clk_id;
485 sci_clk->provider = provider;
486 sci_clk->num_parents = num_parents;
487
488 clks[num_clks] = sci_clk;
489
490 clk_id++;
491 num_clks++;
492 }
493
494 provider->clocks = devm_kmalloc_array(dev, num_clks, sizeof(sci_clk),
495 GFP_KERNEL);
496 if (!provider->clocks)
497 return -ENOMEM;
498
499 memcpy(provider->clocks, clks, num_clks * sizeof(sci_clk));
500
501 provider->num_clocks = num_clks;
502
503 devm_kfree(dev, clks);
504
705 ret = ti_sci_init_clocks(provider); 505 ret = ti_sci_init_clocks(provider);
706 if (ret) { 506 if (ret) {
707 pr_err("ti-sci-init-clocks failed.\n"); 507 pr_err("ti-sci-init-clocks failed.\n");