1 /* 2 * Marvell PXA family clocks 3 * 4 * Copyright (C) 2014 Robert Jarzmik 5 * 6 * Common clock code for PXA clocks ("CKEN" type clocks + DT) 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; version 2 of the License. 11 * 12 */ 13 #ifndef _CLK_PXA_ 14 #define _CLK_PXA_ 15 16 #define CLKCFG_TURBO 0x1 17 #define CLKCFG_FCS 0x2 18 #define CLKCFG_HALFTURBO 0x4 19 #define CLKCFG_FASTBUS 0x8 20 21 #define PARENTS(name) \ 22 static const char *const name ## _parents[] __initconst 23 #define MUX_RO_RATE_RO_OPS(name, clk_name) \ 24 static struct clk_hw name ## _mux_hw; \ 25 static struct clk_hw name ## _rate_hw; \ 26 static struct clk_ops name ## _mux_ops = { \ 27 .get_parent = name ## _get_parent, \ 28 .set_parent = dummy_clk_set_parent, \ 29 }; \ 30 static struct clk_ops name ## _rate_ops = { \ 31 .recalc_rate = name ## _get_rate, \ 32 }; \ 33 static struct clk * __init clk_register_ ## name(void) \ 34 { \ 35 return clk_register_composite(NULL, clk_name, \ 36 name ## _parents, \ 37 ARRAY_SIZE(name ## _parents), \ 38 &name ## _mux_hw, &name ## _mux_ops, \ 39 &name ## _rate_hw, &name ## _rate_ops, \ 40 NULL, NULL, CLK_GET_RATE_NOCACHE); \ 41 } 42 43 #define RATE_RO_OPS(name, clk_name) \ 44 static struct clk_hw name ## _rate_hw; \ 45 static const struct clk_ops name ## _rate_ops = { \ 46 .recalc_rate = name ## _get_rate, \ 47 }; \ 48 static struct clk * __init clk_register_ ## name(void) \ 49 { \ 50 return clk_register_composite(NULL, clk_name, \ 51 name ## _parents, \ 52 ARRAY_SIZE(name ## _parents), \ 53 NULL, NULL, \ 54 &name ## _rate_hw, &name ## _rate_ops, \ 55 NULL, NULL, CLK_GET_RATE_NOCACHE); \ 56 } 57 58 #define RATE_OPS(name, clk_name) \ 59 static struct clk_hw name ## _rate_hw; \ 60 static struct clk_ops name ## _rate_ops = { \ 61 .recalc_rate = name ## _get_rate, \ 62 .set_rate = name ## _set_rate, \ 63 .determine_rate = name ## _determine_rate, \ 64 }; \ 65 static struct clk * __init clk_register_ ## name(void) \ 66 { \ 67 return clk_register_composite(NULL, clk_name, \ 68 name ## _parents, \ 69 ARRAY_SIZE(name ## _parents), \ 70 NULL, NULL, \ 71 &name ## _rate_hw, &name ## _rate_ops, \ 72 NULL, NULL, CLK_GET_RATE_NOCACHE); \ 73 } 74 75 #define MUX_OPS(name, clk_name, flags) \ 76 static struct clk_hw name ## _mux_hw; \ 77 static const struct clk_ops name ## _mux_ops = { \ 78 .get_parent = name ## _get_parent, \ 79 .set_parent = name ## _set_parent, \ 80 .determine_rate = name ## _determine_rate, \ 81 }; \ 82 static struct clk * __init clk_register_ ## name(void) \ 83 { \ 84 return clk_register_composite(NULL, clk_name, \ 85 name ## _parents, \ 86 ARRAY_SIZE(name ## _parents), \ 87 &name ## _mux_hw, &name ## _mux_ops, \ 88 NULL, NULL, \ 89 NULL, NULL, \ 90 CLK_GET_RATE_NOCACHE | flags); \ 91 } 92 93 /* 94 * CKEN clock type 95 * This clock takes it source from 2 possible parents : 96 * - a low power parent 97 * - a normal parent 98 * 99 * +------------+ +-----------+ 100 * | Low Power | --- | x mult_lp | 101 * | Clock | | / div_lp |\ 102 * +------------+ +-----------+ \+-----+ +-----------+ 103 * | Mux |---| CKEN gate | 104 * +------------+ +-----------+ /+-----+ +-----------+ 105 * | High Power | | x mult_hp |/ 106 * | Clock | --- | / div_hp | 107 * +------------+ +-----------+ 108 */ 109 struct desc_clk_cken { 110 struct clk_hw hw; 111 int ckid; 112 const char *name; 113 const char *dev_id; 114 const char *con_id; 115 const char * const *parent_names; 116 struct clk_fixed_factor lp; 117 struct clk_fixed_factor hp; 118 struct clk_gate gate; 119 bool (*is_in_low_power)(void); 120 const unsigned long flags; 121 }; 122 123 #define PXA_CKEN(_dev_id, _con_id, _name, parents, _mult_lp, _div_lp, \ 124 _mult_hp, _div_hp, is_lp, _cken_reg, _cken_bit, flag) \ 125 { .ckid = CLK_ ## _name, .name = #_name, \ 126 .dev_id = _dev_id, .con_id = _con_id, .parent_names = parents,\ 127 .lp = { .mult = _mult_lp, .div = _div_lp }, \ 128 .hp = { .mult = _mult_hp, .div = _div_hp }, \ 129 .is_in_low_power = is_lp, \ 130 .gate = { .reg = (void __iomem *)_cken_reg, .bit_idx = _cken_bit }, \ 131 .flags = flag, \ 132 } 133 #define PXA_CKEN_1RATE(dev_id, con_id, name, parents, cken_reg, \ 134 cken_bit, flag) \ 135 PXA_CKEN(dev_id, con_id, name, parents, 1, 1, 1, 1, \ 136 NULL, cken_reg, cken_bit, flag) 137 138 struct pxa2xx_freq { 139 unsigned long cpll; 140 unsigned int membus_khz; 141 unsigned int cccr; 142 unsigned int div2; 143 unsigned int clkcfg; 144 }; 145 146 static inline int dummy_clk_set_parent(struct clk_hw *hw, u8 index) 147 { 148 return 0; 149 } 150 151 extern void clkdev_pxa_register(int ckid, const char *con_id, 152 const char *dev_id, struct clk *clk); 153 extern int clk_pxa_cken_init(const struct desc_clk_cken *clks, int nb_clks); 154 void clk_pxa_dt_common_init(struct device_node *np); 155 156 void pxa2xx_core_turbo_switch(bool on); 157 void pxa2xx_cpll_change(struct pxa2xx_freq *freq, 158 u32 (*mdrefr_dri)(unsigned int), void __iomem *mdrefr, 159 void __iomem *cccr); 160 int pxa2xx_determine_rate(struct clk_rate_request *req, 161 struct pxa2xx_freq *freqs, int nb_freqs); 162 163 #endif 164