18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Marvell PXA family clocks 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2014 Robert Jarzmik 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Common clock code for PXA clocks ("CKEN" type clocks + DT) 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci#ifndef _CLK_PXA_ 108c2ecf20Sopenharmony_ci#define _CLK_PXA_ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#define CLKCFG_TURBO 0x1 138c2ecf20Sopenharmony_ci#define CLKCFG_FCS 0x2 148c2ecf20Sopenharmony_ci#define CLKCFG_HALFTURBO 0x4 158c2ecf20Sopenharmony_ci#define CLKCFG_FASTBUS 0x8 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#define PARENTS(name) \ 188c2ecf20Sopenharmony_ci static const char *const name ## _parents[] __initconst 198c2ecf20Sopenharmony_ci#define MUX_RO_RATE_RO_OPS(name, clk_name) \ 208c2ecf20Sopenharmony_ci static struct clk_hw name ## _mux_hw; \ 218c2ecf20Sopenharmony_ci static struct clk_hw name ## _rate_hw; \ 228c2ecf20Sopenharmony_ci static const struct clk_ops name ## _mux_ops = { \ 238c2ecf20Sopenharmony_ci .get_parent = name ## _get_parent, \ 248c2ecf20Sopenharmony_ci .set_parent = dummy_clk_set_parent, \ 258c2ecf20Sopenharmony_ci }; \ 268c2ecf20Sopenharmony_ci static const struct clk_ops name ## _rate_ops = { \ 278c2ecf20Sopenharmony_ci .recalc_rate = name ## _get_rate, \ 288c2ecf20Sopenharmony_ci }; \ 298c2ecf20Sopenharmony_ci static struct clk * __init clk_register_ ## name(void) \ 308c2ecf20Sopenharmony_ci { \ 318c2ecf20Sopenharmony_ci return clk_register_composite(NULL, clk_name, \ 328c2ecf20Sopenharmony_ci name ## _parents, \ 338c2ecf20Sopenharmony_ci ARRAY_SIZE(name ## _parents), \ 348c2ecf20Sopenharmony_ci &name ## _mux_hw, &name ## _mux_ops, \ 358c2ecf20Sopenharmony_ci &name ## _rate_hw, &name ## _rate_ops, \ 368c2ecf20Sopenharmony_ci NULL, NULL, CLK_GET_RATE_NOCACHE); \ 378c2ecf20Sopenharmony_ci } 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#define RATE_RO_OPS(name, clk_name) \ 408c2ecf20Sopenharmony_ci static struct clk_hw name ## _rate_hw; \ 418c2ecf20Sopenharmony_ci static const struct clk_ops name ## _rate_ops = { \ 428c2ecf20Sopenharmony_ci .recalc_rate = name ## _get_rate, \ 438c2ecf20Sopenharmony_ci }; \ 448c2ecf20Sopenharmony_ci static struct clk * __init clk_register_ ## name(void) \ 458c2ecf20Sopenharmony_ci { \ 468c2ecf20Sopenharmony_ci return clk_register_composite(NULL, clk_name, \ 478c2ecf20Sopenharmony_ci name ## _parents, \ 488c2ecf20Sopenharmony_ci ARRAY_SIZE(name ## _parents), \ 498c2ecf20Sopenharmony_ci NULL, NULL, \ 508c2ecf20Sopenharmony_ci &name ## _rate_hw, &name ## _rate_ops, \ 518c2ecf20Sopenharmony_ci NULL, NULL, CLK_GET_RATE_NOCACHE); \ 528c2ecf20Sopenharmony_ci } 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci#define RATE_OPS(name, clk_name) \ 558c2ecf20Sopenharmony_ci static struct clk_hw name ## _rate_hw; \ 568c2ecf20Sopenharmony_ci static const struct clk_ops name ## _rate_ops = { \ 578c2ecf20Sopenharmony_ci .recalc_rate = name ## _get_rate, \ 588c2ecf20Sopenharmony_ci .set_rate = name ## _set_rate, \ 598c2ecf20Sopenharmony_ci .determine_rate = name ## _determine_rate, \ 608c2ecf20Sopenharmony_ci }; \ 618c2ecf20Sopenharmony_ci static struct clk * __init clk_register_ ## name(void) \ 628c2ecf20Sopenharmony_ci { \ 638c2ecf20Sopenharmony_ci return clk_register_composite(NULL, clk_name, \ 648c2ecf20Sopenharmony_ci name ## _parents, \ 658c2ecf20Sopenharmony_ci ARRAY_SIZE(name ## _parents), \ 668c2ecf20Sopenharmony_ci NULL, NULL, \ 678c2ecf20Sopenharmony_ci &name ## _rate_hw, &name ## _rate_ops, \ 688c2ecf20Sopenharmony_ci NULL, NULL, CLK_GET_RATE_NOCACHE); \ 698c2ecf20Sopenharmony_ci } 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci#define MUX_OPS(name, clk_name, flags) \ 728c2ecf20Sopenharmony_ci static struct clk_hw name ## _mux_hw; \ 738c2ecf20Sopenharmony_ci static const struct clk_ops name ## _mux_ops = { \ 748c2ecf20Sopenharmony_ci .get_parent = name ## _get_parent, \ 758c2ecf20Sopenharmony_ci .set_parent = name ## _set_parent, \ 768c2ecf20Sopenharmony_ci .determine_rate = name ## _determine_rate, \ 778c2ecf20Sopenharmony_ci }; \ 788c2ecf20Sopenharmony_ci static struct clk * __init clk_register_ ## name(void) \ 798c2ecf20Sopenharmony_ci { \ 808c2ecf20Sopenharmony_ci return clk_register_composite(NULL, clk_name, \ 818c2ecf20Sopenharmony_ci name ## _parents, \ 828c2ecf20Sopenharmony_ci ARRAY_SIZE(name ## _parents), \ 838c2ecf20Sopenharmony_ci &name ## _mux_hw, &name ## _mux_ops, \ 848c2ecf20Sopenharmony_ci NULL, NULL, \ 858c2ecf20Sopenharmony_ci NULL, NULL, \ 868c2ecf20Sopenharmony_ci CLK_GET_RATE_NOCACHE | flags); \ 878c2ecf20Sopenharmony_ci } 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci/* 908c2ecf20Sopenharmony_ci * CKEN clock type 918c2ecf20Sopenharmony_ci * This clock takes it source from 2 possible parents : 928c2ecf20Sopenharmony_ci * - a low power parent 938c2ecf20Sopenharmony_ci * - a normal parent 948c2ecf20Sopenharmony_ci * 958c2ecf20Sopenharmony_ci * +------------+ +-----------+ 968c2ecf20Sopenharmony_ci * | Low Power | --- | x mult_lp | 978c2ecf20Sopenharmony_ci * | Clock | | / div_lp |\ 988c2ecf20Sopenharmony_ci * +------------+ +-----------+ \+-----+ +-----------+ 998c2ecf20Sopenharmony_ci * | Mux |---| CKEN gate | 1008c2ecf20Sopenharmony_ci * +------------+ +-----------+ /+-----+ +-----------+ 1018c2ecf20Sopenharmony_ci * | High Power | | x mult_hp |/ 1028c2ecf20Sopenharmony_ci * | Clock | --- | / div_hp | 1038c2ecf20Sopenharmony_ci * +------------+ +-----------+ 1048c2ecf20Sopenharmony_ci */ 1058c2ecf20Sopenharmony_cistruct desc_clk_cken { 1068c2ecf20Sopenharmony_ci struct clk_hw hw; 1078c2ecf20Sopenharmony_ci int ckid; 1088c2ecf20Sopenharmony_ci const char *name; 1098c2ecf20Sopenharmony_ci const char *dev_id; 1108c2ecf20Sopenharmony_ci const char *con_id; 1118c2ecf20Sopenharmony_ci const char * const *parent_names; 1128c2ecf20Sopenharmony_ci struct clk_fixed_factor lp; 1138c2ecf20Sopenharmony_ci struct clk_fixed_factor hp; 1148c2ecf20Sopenharmony_ci struct clk_gate gate; 1158c2ecf20Sopenharmony_ci bool (*is_in_low_power)(void); 1168c2ecf20Sopenharmony_ci const unsigned long flags; 1178c2ecf20Sopenharmony_ci}; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci#define PXA_CKEN(_dev_id, _con_id, _name, parents, _mult_lp, _div_lp, \ 1208c2ecf20Sopenharmony_ci _mult_hp, _div_hp, is_lp, _cken_reg, _cken_bit, flag) \ 1218c2ecf20Sopenharmony_ci { .ckid = CLK_ ## _name, .name = #_name, \ 1228c2ecf20Sopenharmony_ci .dev_id = _dev_id, .con_id = _con_id, .parent_names = parents,\ 1238c2ecf20Sopenharmony_ci .lp = { .mult = _mult_lp, .div = _div_lp }, \ 1248c2ecf20Sopenharmony_ci .hp = { .mult = _mult_hp, .div = _div_hp }, \ 1258c2ecf20Sopenharmony_ci .is_in_low_power = is_lp, \ 1268c2ecf20Sopenharmony_ci .gate = { .reg = (void __iomem *)_cken_reg, .bit_idx = _cken_bit }, \ 1278c2ecf20Sopenharmony_ci .flags = flag, \ 1288c2ecf20Sopenharmony_ci } 1298c2ecf20Sopenharmony_ci#define PXA_CKEN_1RATE(dev_id, con_id, name, parents, cken_reg, \ 1308c2ecf20Sopenharmony_ci cken_bit, flag) \ 1318c2ecf20Sopenharmony_ci PXA_CKEN(dev_id, con_id, name, parents, 1, 1, 1, 1, \ 1328c2ecf20Sopenharmony_ci NULL, cken_reg, cken_bit, flag) 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistruct pxa2xx_freq { 1358c2ecf20Sopenharmony_ci unsigned long cpll; 1368c2ecf20Sopenharmony_ci unsigned int membus_khz; 1378c2ecf20Sopenharmony_ci unsigned int cccr; 1388c2ecf20Sopenharmony_ci unsigned int div2; 1398c2ecf20Sopenharmony_ci unsigned int clkcfg; 1408c2ecf20Sopenharmony_ci}; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistatic inline int dummy_clk_set_parent(struct clk_hw *hw, u8 index) 1438c2ecf20Sopenharmony_ci{ 1448c2ecf20Sopenharmony_ci return 0; 1458c2ecf20Sopenharmony_ci} 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ciextern void clkdev_pxa_register(int ckid, const char *con_id, 1488c2ecf20Sopenharmony_ci const char *dev_id, struct clk *clk); 1498c2ecf20Sopenharmony_ciextern int clk_pxa_cken_init(const struct desc_clk_cken *clks, int nb_clks); 1508c2ecf20Sopenharmony_civoid clk_pxa_dt_common_init(struct device_node *np); 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_civoid pxa2xx_core_turbo_switch(bool on); 1538c2ecf20Sopenharmony_civoid pxa2xx_cpll_change(struct pxa2xx_freq *freq, 1548c2ecf20Sopenharmony_ci u32 (*mdrefr_dri)(unsigned int), void __iomem *mdrefr, 1558c2ecf20Sopenharmony_ci void __iomem *cccr); 1568c2ecf20Sopenharmony_ciint pxa2xx_determine_rate(struct clk_rate_request *req, 1578c2ecf20Sopenharmony_ci struct pxa2xx_freq *freqs, int nb_freqs); 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci#endif 160