diff options
-rw-r--r-- | drivers/clk/bcm/clk-bcm281xx.c | 132 | ||||
-rw-r--r-- | drivers/clk/bcm/clk-kona-setup.c | 60 | ||||
-rw-r--r-- | drivers/clk/bcm/clk-kona.h | 84 |
3 files changed, 133 insertions, 143 deletions
diff --git a/drivers/clk/bcm/clk-bcm281xx.c b/drivers/clk/bcm/clk-bcm281xx.c index d72f2ae01493..71a65a49f1a4 100644 --- a/drivers/clk/bcm/clk-bcm281xx.c +++ b/drivers/clk/bcm/clk-bcm281xx.c | |||
@@ -41,6 +41,11 @@ static struct peri_clk_data frac_1m_data = { | |||
41 | 41 | ||
42 | static struct ccu_data root_ccu_data = { | 42 | static struct ccu_data root_ccu_data = { |
43 | BCM281XX_CCU_COMMON(root, ROOT), | 43 | BCM281XX_CCU_COMMON(root, ROOT), |
44 | .kona_clks = { | ||
45 | [BCM281XX_ROOT_CCU_FRAC_1M] = | ||
46 | KONA_CLK(root, frac_1m, peri), | ||
47 | [BCM281XX_ROOT_CCU_CLOCK_COUNT] = LAST_KONA_CLK, | ||
48 | }, | ||
44 | }; | 49 | }; |
45 | 50 | ||
46 | /* AON CCU */ | 51 | /* AON CCU */ |
@@ -74,6 +79,15 @@ static struct peri_clk_data pmu_bsc_var_data = { | |||
74 | 79 | ||
75 | static struct ccu_data aon_ccu_data = { | 80 | static struct ccu_data aon_ccu_data = { |
76 | BCM281XX_CCU_COMMON(aon, AON), | 81 | BCM281XX_CCU_COMMON(aon, AON), |
82 | .kona_clks = { | ||
83 | [BCM281XX_AON_CCU_HUB_TIMER] = | ||
84 | KONA_CLK(aon, hub_timer, peri), | ||
85 | [BCM281XX_AON_CCU_PMU_BSC] = | ||
86 | KONA_CLK(aon, pmu_bsc, peri), | ||
87 | [BCM281XX_AON_CCU_PMU_BSC_VAR] = | ||
88 | KONA_CLK(aon, pmu_bsc_var, peri), | ||
89 | [BCM281XX_AON_CCU_CLOCK_COUNT] = LAST_KONA_CLK, | ||
90 | }, | ||
77 | }; | 91 | }; |
78 | 92 | ||
79 | /* Hub CCU */ | 93 | /* Hub CCU */ |
@@ -88,6 +102,11 @@ static struct peri_clk_data tmon_1m_data = { | |||
88 | 102 | ||
89 | static struct ccu_data hub_ccu_data = { | 103 | static struct ccu_data hub_ccu_data = { |
90 | BCM281XX_CCU_COMMON(hub, HUB), | 104 | BCM281XX_CCU_COMMON(hub, HUB), |
105 | .kona_clks = { | ||
106 | [BCM281XX_HUB_CCU_TMON_1M] = | ||
107 | KONA_CLK(hub, tmon_1m, peri), | ||
108 | [BCM281XX_HUB_CCU_CLOCK_COUNT] = LAST_KONA_CLK, | ||
109 | }, | ||
91 | }; | 110 | }; |
92 | 111 | ||
93 | /* Master CCU */ | 112 | /* Master CCU */ |
@@ -175,6 +194,23 @@ static struct peri_clk_data hsic2_12m_data = { | |||
175 | 194 | ||
176 | static struct ccu_data master_ccu_data = { | 195 | static struct ccu_data master_ccu_data = { |
177 | BCM281XX_CCU_COMMON(master, MASTER), | 196 | BCM281XX_CCU_COMMON(master, MASTER), |
197 | .kona_clks = { | ||
198 | [BCM281XX_MASTER_CCU_SDIO1] = | ||
199 | KONA_CLK(master, sdio1, peri), | ||
200 | [BCM281XX_MASTER_CCU_SDIO2] = | ||
201 | KONA_CLK(master, sdio2, peri), | ||
202 | [BCM281XX_MASTER_CCU_SDIO3] = | ||
203 | KONA_CLK(master, sdio3, peri), | ||
204 | [BCM281XX_MASTER_CCU_SDIO4] = | ||
205 | KONA_CLK(master, sdio4, peri), | ||
206 | [BCM281XX_MASTER_CCU_USB_IC] = | ||
207 | KONA_CLK(master, usb_ic, peri), | ||
208 | [BCM281XX_MASTER_CCU_HSIC2_48M] = | ||
209 | KONA_CLK(master, hsic2_48m, peri), | ||
210 | [BCM281XX_MASTER_CCU_HSIC2_12M] = | ||
211 | KONA_CLK(master, hsic2_12m, peri), | ||
212 | [BCM281XX_MASTER_CCU_CLOCK_COUNT] = LAST_KONA_CLK, | ||
213 | }, | ||
178 | }; | 214 | }; |
179 | 215 | ||
180 | /* Slave CCU */ | 216 | /* Slave CCU */ |
@@ -287,96 +323,56 @@ static struct peri_clk_data pwm_data = { | |||
287 | 323 | ||
288 | static struct ccu_data slave_ccu_data = { | 324 | static struct ccu_data slave_ccu_data = { |
289 | BCM281XX_CCU_COMMON(slave, SLAVE), | 325 | BCM281XX_CCU_COMMON(slave, SLAVE), |
326 | .kona_clks = { | ||
327 | [BCM281XX_SLAVE_CCU_UARTB] = | ||
328 | KONA_CLK(slave, uartb, peri), | ||
329 | [BCM281XX_SLAVE_CCU_UARTB2] = | ||
330 | KONA_CLK(slave, uartb2, peri), | ||
331 | [BCM281XX_SLAVE_CCU_UARTB3] = | ||
332 | KONA_CLK(slave, uartb3, peri), | ||
333 | [BCM281XX_SLAVE_CCU_UARTB4] = | ||
334 | KONA_CLK(slave, uartb4, peri), | ||
335 | [BCM281XX_SLAVE_CCU_SSP0] = | ||
336 | KONA_CLK(slave, ssp0, peri), | ||
337 | [BCM281XX_SLAVE_CCU_SSP2] = | ||
338 | KONA_CLK(slave, ssp2, peri), | ||
339 | [BCM281XX_SLAVE_CCU_BSC1] = | ||
340 | KONA_CLK(slave, bsc1, peri), | ||
341 | [BCM281XX_SLAVE_CCU_BSC2] = | ||
342 | KONA_CLK(slave, bsc2, peri), | ||
343 | [BCM281XX_SLAVE_CCU_BSC3] = | ||
344 | KONA_CLK(slave, bsc3, peri), | ||
345 | [BCM281XX_SLAVE_CCU_PWM] = | ||
346 | KONA_CLK(slave, pwm, peri), | ||
347 | [BCM281XX_SLAVE_CCU_CLOCK_COUNT] = LAST_KONA_CLK, | ||
348 | }, | ||
290 | }; | 349 | }; |
291 | 350 | ||
292 | /* | ||
293 | * CCU setup routines | ||
294 | * | ||
295 | * These are called from kona_dt_ccu_setup() to initialize the array | ||
296 | * of clocks provided by the CCU. Once allocated, the entries in | ||
297 | * the array are initialized by calling kona_clk_setup() with the | ||
298 | * initialization data for each clock. They return 0 if successful | ||
299 | * or an error code otherwise. | ||
300 | */ | ||
301 | static int __init bcm281xx_root_ccu_clks_setup(struct ccu_data *ccu) | ||
302 | { | ||
303 | PERI_CLK_SETUP(ccu, BCM281XX_ROOT_CCU_FRAC_1M, frac_1m); | ||
304 | |||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | static int __init bcm281xx_aon_ccu_clks_setup(struct ccu_data *ccu) | ||
309 | { | ||
310 | PERI_CLK_SETUP(ccu, BCM281XX_AON_CCU_HUB_TIMER, hub_timer); | ||
311 | PERI_CLK_SETUP(ccu, BCM281XX_AON_CCU_PMU_BSC, pmu_bsc); | ||
312 | PERI_CLK_SETUP(ccu, BCM281XX_AON_CCU_PMU_BSC_VAR, pmu_bsc_var); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static int __init bcm281xx_hub_ccu_clks_setup(struct ccu_data *ccu) | ||
318 | { | ||
319 | PERI_CLK_SETUP(ccu, BCM281XX_HUB_CCU_TMON_1M, tmon_1m); | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static int __init bcm281xx_master_ccu_clks_setup(struct ccu_data *ccu) | ||
325 | { | ||
326 | PERI_CLK_SETUP(ccu, BCM281XX_MASTER_CCU_SDIO1, sdio1); | ||
327 | PERI_CLK_SETUP(ccu, BCM281XX_MASTER_CCU_SDIO2, sdio2); | ||
328 | PERI_CLK_SETUP(ccu, BCM281XX_MASTER_CCU_SDIO3, sdio3); | ||
329 | PERI_CLK_SETUP(ccu, BCM281XX_MASTER_CCU_SDIO4, sdio4); | ||
330 | PERI_CLK_SETUP(ccu, BCM281XX_MASTER_CCU_USB_IC, usb_ic); | ||
331 | PERI_CLK_SETUP(ccu, BCM281XX_MASTER_CCU_HSIC2_48M, hsic2_48m); | ||
332 | PERI_CLK_SETUP(ccu, BCM281XX_MASTER_CCU_HSIC2_12M, hsic2_12m); | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | static int __init bcm281xx_slave_ccu_clks_setup(struct ccu_data *ccu) | ||
338 | { | ||
339 | PERI_CLK_SETUP(ccu, BCM281XX_SLAVE_CCU_UARTB, uartb); | ||
340 | PERI_CLK_SETUP(ccu, BCM281XX_SLAVE_CCU_UARTB2, uartb2); | ||
341 | PERI_CLK_SETUP(ccu, BCM281XX_SLAVE_CCU_UARTB3, uartb3); | ||
342 | PERI_CLK_SETUP(ccu, BCM281XX_SLAVE_CCU_UARTB4, uartb4); | ||
343 | PERI_CLK_SETUP(ccu, BCM281XX_SLAVE_CCU_SSP0, ssp0); | ||
344 | PERI_CLK_SETUP(ccu, BCM281XX_SLAVE_CCU_SSP2, ssp2); | ||
345 | PERI_CLK_SETUP(ccu, BCM281XX_SLAVE_CCU_BSC1, bsc1); | ||
346 | PERI_CLK_SETUP(ccu, BCM281XX_SLAVE_CCU_BSC2, bsc2); | ||
347 | PERI_CLK_SETUP(ccu, BCM281XX_SLAVE_CCU_BSC3, bsc3); | ||
348 | PERI_CLK_SETUP(ccu, BCM281XX_SLAVE_CCU_PWM, pwm); | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | /* Device tree match table callback functions */ | 351 | /* Device tree match table callback functions */ |
354 | 352 | ||
355 | static void __init kona_dt_root_ccu_setup(struct device_node *node) | 353 | static void __init kona_dt_root_ccu_setup(struct device_node *node) |
356 | { | 354 | { |
357 | kona_dt_ccu_setup(&root_ccu_data, node, bcm281xx_root_ccu_clks_setup); | 355 | kona_dt_ccu_setup(&root_ccu_data, node); |
358 | } | 356 | } |
359 | 357 | ||
360 | static void __init kona_dt_aon_ccu_setup(struct device_node *node) | 358 | static void __init kona_dt_aon_ccu_setup(struct device_node *node) |
361 | { | 359 | { |
362 | kona_dt_ccu_setup(&aon_ccu_data, node, bcm281xx_aon_ccu_clks_setup); | 360 | kona_dt_ccu_setup(&aon_ccu_data, node); |
363 | } | 361 | } |
364 | 362 | ||
365 | static void __init kona_dt_hub_ccu_setup(struct device_node *node) | 363 | static void __init kona_dt_hub_ccu_setup(struct device_node *node) |
366 | { | 364 | { |
367 | kona_dt_ccu_setup(&hub_ccu_data, node, bcm281xx_hub_ccu_clks_setup); | 365 | kona_dt_ccu_setup(&hub_ccu_data, node); |
368 | } | 366 | } |
369 | 367 | ||
370 | static void __init kona_dt_master_ccu_setup(struct device_node *node) | 368 | static void __init kona_dt_master_ccu_setup(struct device_node *node) |
371 | { | 369 | { |
372 | kona_dt_ccu_setup(&master_ccu_data, node, | 370 | kona_dt_ccu_setup(&master_ccu_data, node); |
373 | bcm281xx_master_ccu_clks_setup); | ||
374 | } | 371 | } |
375 | 372 | ||
376 | static void __init kona_dt_slave_ccu_setup(struct device_node *node) | 373 | static void __init kona_dt_slave_ccu_setup(struct device_node *node) |
377 | { | 374 | { |
378 | kona_dt_ccu_setup(&slave_ccu_data, node, | 375 | kona_dt_ccu_setup(&slave_ccu_data, node); |
379 | bcm281xx_slave_ccu_clks_setup); | ||
380 | } | 376 | } |
381 | 377 | ||
382 | CLK_OF_DECLARE(bcm281xx_root_ccu, BCM281XX_DT_ROOT_CCU_COMPAT, | 378 | CLK_OF_DECLARE(bcm281xx_root_ccu, BCM281XX_DT_ROOT_CCU_COMPAT, |
diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c index 4d1ca5372eff..825a2f2ab052 100644 --- a/drivers/clk/bcm/clk-kona-setup.c +++ b/drivers/clk/bcm/clk-kona-setup.c | |||
@@ -567,7 +567,6 @@ static void peri_clk_teardown(struct peri_clk_data *data, | |||
567 | struct clk_init_data *init_data) | 567 | struct clk_init_data *init_data) |
568 | { | 568 | { |
569 | clk_sel_teardown(&data->sel, init_data); | 569 | clk_sel_teardown(&data->sel, init_data); |
570 | init_data->ops = NULL; | ||
571 | } | 570 | } |
572 | 571 | ||
573 | /* | 572 | /* |
@@ -576,10 +575,9 @@ static void peri_clk_teardown(struct peri_clk_data *data, | |||
576 | * that can be assigned if the clock has one or more parent clocks | 575 | * that can be assigned if the clock has one or more parent clocks |
577 | * associated with it. | 576 | * associated with it. |
578 | */ | 577 | */ |
579 | static int peri_clk_setup(struct ccu_data *ccu, struct peri_clk_data *data, | 578 | static int |
580 | struct clk_init_data *init_data) | 579 | peri_clk_setup(struct peri_clk_data *data, struct clk_init_data *init_data) |
581 | { | 580 | { |
582 | init_data->ops = &kona_peri_clk_ops; | ||
583 | init_data->flags = CLK_IGNORE_UNUSED; | 581 | init_data->flags = CLK_IGNORE_UNUSED; |
584 | 582 | ||
585 | return clk_sel_setup(data->clocks, &data->sel, init_data); | 583 | return clk_sel_setup(data->clocks, &data->sel, init_data); |
@@ -617,39 +615,26 @@ static void kona_clk_teardown(struct clk *clk) | |||
617 | bcm_clk_teardown(bcm_clk); | 615 | bcm_clk_teardown(bcm_clk); |
618 | } | 616 | } |
619 | 617 | ||
620 | struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name, | 618 | struct clk *kona_clk_setup(struct kona_clk *bcm_clk) |
621 | enum bcm_clk_type type, void *data) | ||
622 | { | 619 | { |
623 | struct kona_clk *bcm_clk; | 620 | struct clk_init_data *init_data = &bcm_clk->init_data; |
624 | struct clk_init_data *init_data; | ||
625 | struct clk *clk = NULL; | 621 | struct clk *clk = NULL; |
626 | 622 | ||
627 | bcm_clk = kzalloc(sizeof(*bcm_clk), GFP_KERNEL); | 623 | switch (bcm_clk->type) { |
628 | if (!bcm_clk) { | ||
629 | pr_err("%s: failed to allocate bcm_clk for %s\n", __func__, | ||
630 | name); | ||
631 | return NULL; | ||
632 | } | ||
633 | bcm_clk->ccu = ccu; | ||
634 | bcm_clk->init_data.name = name; | ||
635 | |||
636 | init_data = &bcm_clk->init_data; | ||
637 | init_data->name = name; | ||
638 | switch (type) { | ||
639 | case bcm_clk_peri: | 624 | case bcm_clk_peri: |
640 | if (peri_clk_setup(ccu, data, init_data)) | 625 | if (peri_clk_setup(bcm_clk->u.data, init_data)) |
641 | goto out_free; | 626 | return NULL; |
642 | break; | 627 | break; |
643 | default: | 628 | default: |
644 | data = NULL; | 629 | pr_err("%s: clock type %d invalid for %s\n", __func__, |
645 | break; | 630 | (int)bcm_clk->type, init_data->name); |
631 | return NULL; | ||
646 | } | 632 | } |
647 | bcm_clk->type = type; | ||
648 | bcm_clk->u.data = data; | ||
649 | 633 | ||
650 | /* Make sure everything makes sense before we set it up */ | 634 | /* Make sure everything makes sense before we set it up */ |
651 | if (!kona_clk_valid(bcm_clk)) { | 635 | if (!kona_clk_valid(bcm_clk)) { |
652 | pr_err("%s: clock data invalid for %s\n", __func__, name); | 636 | pr_err("%s: clock data invalid for %s\n", __func__, |
637 | init_data->name); | ||
653 | goto out_teardown; | 638 | goto out_teardown; |
654 | } | 639 | } |
655 | 640 | ||
@@ -657,7 +642,7 @@ struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name, | |||
657 | clk = clk_register(NULL, &bcm_clk->hw); | 642 | clk = clk_register(NULL, &bcm_clk->hw); |
658 | if (IS_ERR(clk)) { | 643 | if (IS_ERR(clk)) { |
659 | pr_err("%s: error registering clock %s (%ld)\n", __func__, | 644 | pr_err("%s: error registering clock %s (%ld)\n", __func__, |
660 | name, PTR_ERR(clk)); | 645 | init_data->name, PTR_ERR(clk)); |
661 | goto out_teardown; | 646 | goto out_teardown; |
662 | } | 647 | } |
663 | BUG_ON(!clk); | 648 | BUG_ON(!clk); |
@@ -665,8 +650,6 @@ struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name, | |||
665 | return clk; | 650 | return clk; |
666 | out_teardown: | 651 | out_teardown: |
667 | bcm_clk_teardown(bcm_clk); | 652 | bcm_clk_teardown(bcm_clk); |
668 | out_free: | ||
669 | kfree(bcm_clk); | ||
670 | 653 | ||
671 | return NULL; | 654 | return NULL; |
672 | } | 655 | } |
@@ -701,11 +684,11 @@ static void kona_ccu_teardown(struct ccu_data *ccu) | |||
701 | * initialize the array of clocks provided by the CCU. | 684 | * initialize the array of clocks provided by the CCU. |
702 | */ | 685 | */ |
703 | void __init kona_dt_ccu_setup(struct ccu_data *ccu, | 686 | void __init kona_dt_ccu_setup(struct ccu_data *ccu, |
704 | struct device_node *node, | 687 | struct device_node *node) |
705 | int (*ccu_clks_setup)(struct ccu_data *)) | ||
706 | { | 688 | { |
707 | struct resource res = { 0 }; | 689 | struct resource res = { 0 }; |
708 | resource_size_t range; | 690 | resource_size_t range; |
691 | unsigned int i; | ||
709 | int ret; | 692 | int ret; |
710 | 693 | ||
711 | if (ccu->clk_data.clk_num) { | 694 | if (ccu->clk_data.clk_num) { |
@@ -744,9 +727,16 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu, | |||
744 | ccu->node = of_node_get(node); | 727 | ccu->node = of_node_get(node); |
745 | list_add_tail(&ccu->links, &ccu_list); | 728 | list_add_tail(&ccu->links, &ccu_list); |
746 | 729 | ||
747 | /* Set up clocks array (in ccu->clk_data) */ | 730 | /* |
748 | if (ccu_clks_setup(ccu)) | 731 | * Set up each defined kona clock and save the result in |
749 | goto out_err; | 732 | * the clock framework clock array (in ccu->data). Then |
733 | * register as a provider for these clocks. | ||
734 | */ | ||
735 | for (i = 0; i < ccu->clk_data.clk_num; i++) { | ||
736 | if (!ccu->kona_clks[i].ccu) | ||
737 | continue; | ||
738 | ccu->clk_data.clks[i] = kona_clk_setup(&ccu->kona_clks[i]); | ||
739 | } | ||
750 | 740 | ||
751 | ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->clk_data); | 741 | ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->clk_data); |
752 | if (ret) { | 742 | if (ret) { |
diff --git a/drivers/clk/bcm/clk-kona.h b/drivers/clk/bcm/clk-kona.h index 108c2647ca28..05d74779a564 100644 --- a/drivers/clk/bcm/clk-kona.h +++ b/drivers/clk/bcm/clk-kona.h | |||
@@ -71,35 +71,6 @@ enum bcm_clk_type { | |||
71 | }; | 71 | }; |
72 | 72 | ||
73 | /* | 73 | /* |
74 | * Each CCU defines a mapped area of memory containing registers | ||
75 | * used to manage clocks implemented by the CCU. Access to memory | ||
76 | * within the CCU's space is serialized by a spinlock. Before any | ||
77 | * (other) address can be written, a special access "password" value | ||
78 | * must be written to its WR_ACCESS register (located at the base | ||
79 | * address of the range). We keep track of the name of each CCU as | ||
80 | * it is set up, and maintain them in a list. | ||
81 | */ | ||
82 | struct ccu_data { | ||
83 | void __iomem *base; /* base of mapped address space */ | ||
84 | spinlock_t lock; /* serialization lock */ | ||
85 | bool write_enabled; /* write access is currently enabled */ | ||
86 | struct list_head links; /* for ccu_list */ | ||
87 | struct device_node *node; | ||
88 | struct clk_onecell_data clk_data; | ||
89 | const char *name; | ||
90 | u32 range; /* byte range of address space */ | ||
91 | }; | ||
92 | |||
93 | /* Initialization for common fields in a Kona ccu_data structure */ | ||
94 | #define KONA_CCU_COMMON(_prefix, _name, _ucase_name) \ | ||
95 | .name = #_name "_ccu", \ | ||
96 | .lock = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock), \ | ||
97 | .links = LIST_HEAD_INIT(_name ## _ccu_data.links), \ | ||
98 | .clk_data = { \ | ||
99 | .clk_num = _prefix ## _ ## _ucase_name ## _CCU_CLOCK_COUNT, \ | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * Gating control and status is managed by a 32-bit gate register. | 74 | * Gating control and status is managed by a 32-bit gate register. |
104 | * | 75 | * |
105 | * There are several types of gating available: | 76 | * There are several types of gating available: |
@@ -393,17 +364,52 @@ struct kona_clk { | |||
393 | #define to_kona_clk(_hw) \ | 364 | #define to_kona_clk(_hw) \ |
394 | container_of(_hw, struct kona_clk, hw) | 365 | container_of(_hw, struct kona_clk, hw) |
395 | 366 | ||
396 | /* Exported globals */ | 367 | /* Initialization macro for an entry in a CCU's kona_clks[] array. */ |
368 | #define KONA_CLK(_ccu_name, _clk_name, _type) \ | ||
369 | { \ | ||
370 | .init_data = { \ | ||
371 | .name = #_clk_name, \ | ||
372 | .ops = &kona_ ## _type ## _clk_ops, \ | ||
373 | }, \ | ||
374 | .ccu = &_ccu_name ## _ccu_data, \ | ||
375 | .type = bcm_clk_ ## _type, \ | ||
376 | .u.data = &_clk_name ## _data, \ | ||
377 | } | ||
378 | #define LAST_KONA_CLK { .type = bcm_clk_none } | ||
397 | 379 | ||
398 | extern struct clk_ops kona_peri_clk_ops; | 380 | /* |
381 | * Each CCU defines a mapped area of memory containing registers | ||
382 | * used to manage clocks implemented by the CCU. Access to memory | ||
383 | * within the CCU's space is serialized by a spinlock. Before any | ||
384 | * (other) address can be written, a special access "password" value | ||
385 | * must be written to its WR_ACCESS register (located at the base | ||
386 | * address of the range). We keep track of the name of each CCU as | ||
387 | * it is set up, and maintain them in a list. | ||
388 | */ | ||
389 | struct ccu_data { | ||
390 | void __iomem *base; /* base of mapped address space */ | ||
391 | spinlock_t lock; /* serialization lock */ | ||
392 | bool write_enabled; /* write access is currently enabled */ | ||
393 | struct list_head links; /* for ccu_list */ | ||
394 | struct device_node *node; | ||
395 | struct clk_onecell_data clk_data; | ||
396 | const char *name; | ||
397 | u32 range; /* byte range of address space */ | ||
398 | struct kona_clk kona_clks[]; /* must be last */ | ||
399 | }; | ||
399 | 400 | ||
400 | /* Help functions */ | 401 | /* Initialization for common fields in a Kona ccu_data structure */ |
402 | #define KONA_CCU_COMMON(_prefix, _name, _ccuname) \ | ||
403 | .name = #_name "_ccu", \ | ||
404 | .lock = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock), \ | ||
405 | .links = LIST_HEAD_INIT(_name ## _ccu_data.links), \ | ||
406 | .clk_data = { \ | ||
407 | .clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT, \ | ||
408 | } | ||
401 | 409 | ||
402 | #define KONA_CLK_SETUP(_ccu, _type, _name) \ | 410 | /* Exported globals */ |
403 | kona_clk_setup((_ccu), #_name, bcm_clk_## _type, &_name ## _data) | ||
404 | 411 | ||
405 | #define PERI_CLK_SETUP(_ccu, _id, _name) \ | 412 | extern struct clk_ops kona_peri_clk_ops; |
406 | (_ccu)->clk_data.clks[_id] = KONA_CLK_SETUP((_ccu), peri, _name) | ||
407 | 413 | ||
408 | /* Externally visible functions */ | 414 | /* Externally visible functions */ |
409 | 415 | ||
@@ -412,11 +418,9 @@ extern u64 scaled_div_max(struct bcm_clk_div *div); | |||
412 | extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, | 418 | extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, |
413 | u32 billionths); | 419 | u32 billionths); |
414 | 420 | ||
415 | extern struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name, | 421 | extern struct clk *kona_clk_setup(struct kona_clk *bcm_clk); |
416 | enum bcm_clk_type type, void *data); | ||
417 | extern void __init kona_dt_ccu_setup(struct ccu_data *ccu, | 422 | extern void __init kona_dt_ccu_setup(struct ccu_data *ccu, |
418 | struct device_node *node, | 423 | struct device_node *node); |
419 | int (*ccu_clks_setup)(struct ccu_data *)); | ||
420 | extern bool __init kona_ccu_init(struct ccu_data *ccu); | 424 | extern bool __init kona_ccu_init(struct ccu_data *ccu); |
421 | 425 | ||
422 | #endif /* _CLK_KONA_H */ | 426 | #endif /* _CLK_KONA_H */ |