aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGabriel Fernandez <gabriel.fernandez@st.com>2018-03-08 11:53:59 -0500
committerMichael Turquette <mturquette@baylibre.com>2018-03-11 18:40:33 -0400
commita97703c59f653f75814865c22ae6b16f5c477530 (patch)
tree1cd0b4df0e90609a8241bffd0b6d13b6b1d0adc6
parentc6cf4d3248980c5e1998ce21f3c2d86502f7e1a9 (diff)
clk: stm32mp1: add Post-dividers for PLL
Each PLL has 3 outputs with post-dividers. pll1_p is dedicated for Cortex-A7 pll1_q is not connected pll1_r is not connected pll2_p is dedicated for AXI pll2_q is dedicated for GPU pll2_r is dedicated for DDR pll3_p is dedicated for mcu pll3_q is for Peripheral Kernel Clock pll3_r is for Peripheral Kernel Clock pll4_p is for Peripheral Kernel Clock pll4_q is for Peripheral Kernel Clock pll4_r is for Peripheral Kernel Clock Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com> Signed-off-by: Michael Turquette <mturquette@baylibre.com>
-rw-r--r--drivers/clk/clk-stm32mp1.c221
1 files changed, 221 insertions, 0 deletions
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index d62a3a94cc67..3a99ad7f7048 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -166,6 +166,23 @@ struct stm32_gate_cfg {
166 const struct clk_ops *ops; 166 const struct clk_ops *ops;
167}; 167};
168 168
169struct stm32_div_cfg {
170 struct div_cfg *div;
171 const struct clk_ops *ops;
172};
173
174struct stm32_mux_cfg {
175 struct mux_cfg *mux;
176 const struct clk_ops *ops;
177};
178
179/* STM32 Composite clock */
180struct stm32_composite_cfg {
181 const struct stm32_gate_cfg *gate;
182 const struct stm32_div_cfg *div;
183 const struct stm32_mux_cfg *mux;
184};
185
169static struct clk_hw * 186static struct clk_hw *
170_clk_hw_register_gate(struct device *dev, 187_clk_hw_register_gate(struct device *dev,
171 struct clk_hw_onecell_data *clk_data, 188 struct clk_hw_onecell_data *clk_data,
@@ -259,6 +276,51 @@ const struct clk_ops mp1_gate_clk_ops = {
259 .is_enabled = clk_gate_is_enabled, 276 .is_enabled = clk_gate_is_enabled,
260}; 277};
261 278
279static struct clk_hw *_get_stm32_mux(void __iomem *base,
280 const struct stm32_mux_cfg *cfg,
281 spinlock_t *lock)
282{
283 struct clk_mux *mux;
284 struct clk_hw *mux_hw;
285
286 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
287 if (!mux)
288 return ERR_PTR(-ENOMEM);
289
290 mux->reg = cfg->mux->reg_off + base;
291 mux->shift = cfg->mux->shift;
292 mux->mask = (1 << cfg->mux->width) - 1;
293 mux->flags = cfg->mux->mux_flags;
294 mux->table = cfg->mux->table;
295
296 mux->lock = lock;
297
298 mux_hw = &mux->hw;
299
300 return mux_hw;
301}
302
303static struct clk_hw *_get_stm32_div(void __iomem *base,
304 const struct stm32_div_cfg *cfg,
305 spinlock_t *lock)
306{
307 struct clk_divider *div;
308
309 div = kzalloc(sizeof(*div), GFP_KERNEL);
310
311 if (!div)
312 return ERR_PTR(-ENOMEM);
313
314 div->reg = cfg->div->reg_off + base;
315 div->shift = cfg->div->shift;
316 div->width = cfg->div->width;
317 div->flags = cfg->div->div_flags;
318 div->table = cfg->div->table;
319 div->lock = lock;
320
321 return &div->hw;
322}
323
262static struct clk_hw * 324static struct clk_hw *
263_get_stm32_gate(void __iomem *base, 325_get_stm32_gate(void __iomem *base,
264 const struct stm32_gate_cfg *cfg, spinlock_t *lock) 326 const struct stm32_gate_cfg *cfg, spinlock_t *lock)
@@ -322,6 +384,61 @@ clk_stm32_register_gate_ops(struct device *dev,
322 return hw; 384 return hw;
323} 385}
324 386
387static struct clk_hw *
388clk_stm32_register_composite(struct device *dev,
389 const char *name, const char * const *parent_names,
390 int num_parents, void __iomem *base,
391 const struct stm32_composite_cfg *cfg,
392 unsigned long flags, spinlock_t *lock)
393{
394 const struct clk_ops *mux_ops, *div_ops, *gate_ops;
395 struct clk_hw *mux_hw, *div_hw, *gate_hw;
396
397 mux_hw = NULL;
398 div_hw = NULL;
399 gate_hw = NULL;
400 mux_ops = NULL;
401 div_ops = NULL;
402 gate_ops = NULL;
403
404 if (cfg->mux) {
405 mux_hw = _get_stm32_mux(base, cfg->mux, lock);
406
407 if (!IS_ERR(mux_hw)) {
408 mux_ops = &clk_mux_ops;
409
410 if (cfg->mux->ops)
411 mux_ops = cfg->mux->ops;
412 }
413 }
414
415 if (cfg->div) {
416 div_hw = _get_stm32_div(base, cfg->div, lock);
417
418 if (!IS_ERR(div_hw)) {
419 div_ops = &clk_divider_ops;
420
421 if (cfg->div->ops)
422 div_ops = cfg->div->ops;
423 }
424 }
425
426 if (cfg->gate) {
427 gate_hw = _get_stm32_gate(base, cfg->gate, lock);
428
429 if (!IS_ERR(gate_hw)) {
430 gate_ops = &clk_gate_ops;
431
432 if (cfg->gate->ops)
433 gate_ops = cfg->gate->ops;
434 }
435 }
436
437 return clk_hw_register_composite(dev, name, parent_names, num_parents,
438 mux_hw, mux_ops, div_hw, div_ops,
439 gate_hw, gate_ops, flags);
440}
441
325/* STM32 PLL */ 442/* STM32 PLL */
326 443
327struct stm32_pll_obj { 444struct stm32_pll_obj {
@@ -527,6 +644,17 @@ _clk_stm32_register_gate(struct device *dev,
527 lock); 644 lock);
528} 645}
529 646
647static struct clk_hw *
648_clk_stm32_register_composite(struct device *dev,
649 struct clk_hw_onecell_data *clk_data,
650 void __iomem *base, spinlock_t *lock,
651 const struct clock_config *cfg)
652{
653 return clk_stm32_register_composite(dev, cfg->name, cfg->parent_names,
654 cfg->num_parents, base, cfg->cfg,
655 cfg->flags, lock);
656}
657
530#define GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\ 658#define GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
531{\ 659{\
532 .id = _id,\ 660 .id = _id,\
@@ -624,6 +752,10 @@ _clk_stm32_register_gate(struct device *dev,
624 .ops = _ops,\ 752 .ops = _ops,\
625 }) 753 })
626 754
755#define _GATE(_gate_offset, _gate_bit_idx, _gate_flags)\
756 _STM32_GATE(_gate_offset, _gate_bit_idx, _gate_flags,\
757 NULL)\
758
627#define _GATE_MP1(_gate_offset, _gate_bit_idx, _gate_flags)\ 759#define _GATE_MP1(_gate_offset, _gate_bit_idx, _gate_flags)\
628 _STM32_GATE(_gate_offset, _gate_bit_idx, _gate_flags,\ 760 _STM32_GATE(_gate_offset, _gate_bit_idx, _gate_flags,\
629 &mp1_gate_clk_ops)\ 761 &mp1_gate_clk_ops)\
@@ -632,6 +764,44 @@ _clk_stm32_register_gate(struct device *dev,
632 STM32_GATE(_id, _name, _parent, _flags,\ 764 STM32_GATE(_id, _name, _parent, _flags,\
633 _GATE_MP1(_offset, _bit_idx, _gate_flags)) 765 _GATE_MP1(_offset, _bit_idx, _gate_flags))
634 766
767#define _STM32_DIV(_div_offset, _div_shift, _div_width,\
768 _div_flags, _div_table, _ops)\
769 .div = &(struct stm32_div_cfg) {\
770 &(struct div_cfg) {\
771 .reg_off = _div_offset,\
772 .shift = _div_shift,\
773 .width = _div_width,\
774 .div_flags = _div_flags,\
775 .table = _div_table,\
776 },\
777 .ops = _ops,\
778 }
779
780#define _DIV(_div_offset, _div_shift, _div_width, _div_flags, _div_table)\
781 _STM32_DIV(_div_offset, _div_shift, _div_width,\
782 _div_flags, _div_table, NULL)\
783
784#define PARENT(_parent) ((const char *[]) { _parent})
785
786#define _NO_MUX .mux = NULL
787#define _NO_DIV .div = NULL
788#define _NO_GATE .gate = NULL
789
790#define COMPOSITE(_id, _name, _parents, _flags, _gate, _mux, _div)\
791{\
792 .id = _id,\
793 .name = _name,\
794 .parent_names = _parents,\
795 .num_parents = ARRAY_SIZE(_parents),\
796 .flags = _flags,\
797 .cfg = &(struct stm32_composite_cfg) {\
798 _gate,\
799 _mux,\
800 _div,\
801 },\
802 .func = _clk_stm32_register_composite,\
803}
804
635static const struct clock_config stm32mp1_clock_cfg[] = { 805static const struct clock_config stm32mp1_clock_cfg[] = {
636 /* Oscillator divider */ 806 /* Oscillator divider */
637 DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2, 807 DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2,
@@ -661,6 +831,57 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
661 PLL(PLL2, "pll2", "ref1", CLK_IGNORE_UNUSED, RCC_PLL2CR), 831 PLL(PLL2, "pll2", "ref1", CLK_IGNORE_UNUSED, RCC_PLL2CR),
662 PLL(PLL3, "pll3", "ref3", CLK_IGNORE_UNUSED, RCC_PLL3CR), 832 PLL(PLL3, "pll3", "ref3", CLK_IGNORE_UNUSED, RCC_PLL3CR),
663 PLL(PLL4, "pll4", "ref4", CLK_IGNORE_UNUSED, RCC_PLL4CR), 833 PLL(PLL4, "pll4", "ref4", CLK_IGNORE_UNUSED, RCC_PLL4CR),
834
835 /* ODF */
836 COMPOSITE(PLL1_P, "pll1_p", PARENT("pll1"), 0,
837 _GATE(RCC_PLL1CR, 4, 0),
838 _NO_MUX,
839 _DIV(RCC_PLL1CFGR2, 0, 7, 0, NULL)),
840
841 COMPOSITE(PLL2_P, "pll2_p", PARENT("pll2"), 0,
842 _GATE(RCC_PLL2CR, 4, 0),
843 _NO_MUX,
844 _DIV(RCC_PLL2CFGR2, 0, 7, 0, NULL)),
845
846 COMPOSITE(PLL2_Q, "pll2_q", PARENT("pll2"), 0,
847 _GATE(RCC_PLL2CR, 5, 0),
848 _NO_MUX,
849 _DIV(RCC_PLL2CFGR2, 8, 7, 0, NULL)),
850
851 COMPOSITE(PLL2_R, "pll2_r", PARENT("pll2"), CLK_IS_CRITICAL,
852 _GATE(RCC_PLL2CR, 6, 0),
853 _NO_MUX,
854 _DIV(RCC_PLL2CFGR2, 16, 7, 0, NULL)),
855
856 COMPOSITE(PLL3_P, "pll3_p", PARENT("pll3"), 0,
857 _GATE(RCC_PLL3CR, 4, 0),
858 _NO_MUX,
859 _DIV(RCC_PLL3CFGR2, 0, 7, 0, NULL)),
860
861 COMPOSITE(PLL3_Q, "pll3_q", PARENT("pll3"), 0,
862 _GATE(RCC_PLL3CR, 5, 0),
863 _NO_MUX,
864 _DIV(RCC_PLL3CFGR2, 8, 7, 0, NULL)),
865
866 COMPOSITE(PLL3_R, "pll3_r", PARENT("pll3"), 0,
867 _GATE(RCC_PLL3CR, 6, 0),
868 _NO_MUX,
869 _DIV(RCC_PLL3CFGR2, 16, 7, 0, NULL)),
870
871 COMPOSITE(PLL4_P, "pll4_p", PARENT("pll4"), 0,
872 _GATE(RCC_PLL4CR, 4, 0),
873 _NO_MUX,
874 _DIV(RCC_PLL4CFGR2, 0, 7, 0, NULL)),
875
876 COMPOSITE(PLL4_Q, "pll4_q", PARENT("pll4"), 0,
877 _GATE(RCC_PLL4CR, 5, 0),
878 _NO_MUX,
879 _DIV(RCC_PLL4CFGR2, 8, 7, 0, NULL)),
880
881 COMPOSITE(PLL4_R, "pll4_r", PARENT("pll4"), 0,
882 _GATE(RCC_PLL4CR, 6, 0),
883 _NO_MUX,
884 _DIV(RCC_PLL4CFGR2, 16, 7, 0, NULL)),
664}; 885};
665 886
666struct stm32_clock_match_data { 887struct stm32_clock_match_data {