18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright 2015 Linaro Ltd. 48c2ecf20Sopenharmony_ci * Copyright (C) 2014 ZTE Corporation. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifndef __ZTE_CLK_H 88c2ecf20Sopenharmony_ci#define __ZTE_CLK_H 98c2ecf20Sopenharmony_ci#include <linux/clk-provider.h> 108c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#define PNAME(x) static const char *x[] 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistruct zx_pll_config { 158c2ecf20Sopenharmony_ci unsigned long rate; 168c2ecf20Sopenharmony_ci u32 cfg0; 178c2ecf20Sopenharmony_ci u32 cfg1; 188c2ecf20Sopenharmony_ci}; 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_cistruct clk_zx_pll { 218c2ecf20Sopenharmony_ci struct clk_hw hw; 228c2ecf20Sopenharmony_ci void __iomem *reg_base; 238c2ecf20Sopenharmony_ci const struct zx_pll_config *lookup_table; /* order by rate asc */ 248c2ecf20Sopenharmony_ci int count; 258c2ecf20Sopenharmony_ci spinlock_t *lock; 268c2ecf20Sopenharmony_ci u8 pd_bit; /* power down bit */ 278c2ecf20Sopenharmony_ci u8 lock_bit; /* pll lock flag bit */ 288c2ecf20Sopenharmony_ci}; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci#define PLL_RATE(_rate, _cfg0, _cfg1) \ 318c2ecf20Sopenharmony_ci{ \ 328c2ecf20Sopenharmony_ci .rate = _rate, \ 338c2ecf20Sopenharmony_ci .cfg0 = _cfg0, \ 348c2ecf20Sopenharmony_ci .cfg1 = _cfg1, \ 358c2ecf20Sopenharmony_ci} 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#define ZX_PLL(_name, _parent, _reg, _table, _pd, _lock) \ 388c2ecf20Sopenharmony_ci{ \ 398c2ecf20Sopenharmony_ci .reg_base = (void __iomem *) _reg, \ 408c2ecf20Sopenharmony_ci .lookup_table = _table, \ 418c2ecf20Sopenharmony_ci .count = ARRAY_SIZE(_table), \ 428c2ecf20Sopenharmony_ci .pd_bit = _pd, \ 438c2ecf20Sopenharmony_ci .lock_bit = _lock, \ 448c2ecf20Sopenharmony_ci .hw.init = CLK_HW_INIT(_name, _parent, &zx_pll_ops, \ 458c2ecf20Sopenharmony_ci CLK_GET_RATE_NOCACHE), \ 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci/* 498c2ecf20Sopenharmony_ci * The pd_bit is not available on ZX296718, so let's pass something 508c2ecf20Sopenharmony_ci * bigger than 31, e.g. 0xff, to indicate that. 518c2ecf20Sopenharmony_ci */ 528c2ecf20Sopenharmony_ci#define ZX296718_PLL(_name, _parent, _reg, _table) \ 538c2ecf20Sopenharmony_ciZX_PLL(_name, _parent, _reg, _table, 0xff, 30) 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistruct zx_clk_gate { 568c2ecf20Sopenharmony_ci struct clk_gate gate; 578c2ecf20Sopenharmony_ci u16 id; 588c2ecf20Sopenharmony_ci}; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci#define GATE(_id, _name, _parent, _reg, _bit, _flag, _gflags) \ 618c2ecf20Sopenharmony_ci{ \ 628c2ecf20Sopenharmony_ci .gate = { \ 638c2ecf20Sopenharmony_ci .reg = (void __iomem *) _reg, \ 648c2ecf20Sopenharmony_ci .bit_idx = (_bit), \ 658c2ecf20Sopenharmony_ci .flags = _gflags, \ 668c2ecf20Sopenharmony_ci .lock = &clk_lock, \ 678c2ecf20Sopenharmony_ci .hw.init = CLK_HW_INIT(_name, \ 688c2ecf20Sopenharmony_ci _parent, \ 698c2ecf20Sopenharmony_ci &clk_gate_ops, \ 708c2ecf20Sopenharmony_ci _flag | CLK_IGNORE_UNUSED), \ 718c2ecf20Sopenharmony_ci }, \ 728c2ecf20Sopenharmony_ci .id = _id, \ 738c2ecf20Sopenharmony_ci} 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistruct zx_clk_fixed_factor { 768c2ecf20Sopenharmony_ci struct clk_fixed_factor factor; 778c2ecf20Sopenharmony_ci u16 id; 788c2ecf20Sopenharmony_ci}; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci#define FFACTOR(_id, _name, _parent, _mult, _div, _flag) \ 818c2ecf20Sopenharmony_ci{ \ 828c2ecf20Sopenharmony_ci .factor = { \ 838c2ecf20Sopenharmony_ci .div = _div, \ 848c2ecf20Sopenharmony_ci .mult = _mult, \ 858c2ecf20Sopenharmony_ci .hw.init = CLK_HW_INIT(_name, \ 868c2ecf20Sopenharmony_ci _parent, \ 878c2ecf20Sopenharmony_ci &clk_fixed_factor_ops, \ 888c2ecf20Sopenharmony_ci _flag), \ 898c2ecf20Sopenharmony_ci }, \ 908c2ecf20Sopenharmony_ci .id = _id, \ 918c2ecf20Sopenharmony_ci} 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistruct zx_clk_mux { 948c2ecf20Sopenharmony_ci struct clk_mux mux; 958c2ecf20Sopenharmony_ci u16 id; 968c2ecf20Sopenharmony_ci}; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci#define MUX_F(_id, _name, _parent, _reg, _shift, _width, _flag, _mflag) \ 998c2ecf20Sopenharmony_ci{ \ 1008c2ecf20Sopenharmony_ci .mux = { \ 1018c2ecf20Sopenharmony_ci .reg = (void __iomem *) _reg, \ 1028c2ecf20Sopenharmony_ci .mask = BIT(_width) - 1, \ 1038c2ecf20Sopenharmony_ci .shift = _shift, \ 1048c2ecf20Sopenharmony_ci .flags = _mflag, \ 1058c2ecf20Sopenharmony_ci .lock = &clk_lock, \ 1068c2ecf20Sopenharmony_ci .hw.init = CLK_HW_INIT_PARENTS(_name, \ 1078c2ecf20Sopenharmony_ci _parent, \ 1088c2ecf20Sopenharmony_ci &clk_mux_ops, \ 1098c2ecf20Sopenharmony_ci _flag), \ 1108c2ecf20Sopenharmony_ci }, \ 1118c2ecf20Sopenharmony_ci .id = _id, \ 1128c2ecf20Sopenharmony_ci} 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci#define MUX(_id, _name, _parent, _reg, _shift, _width) \ 1158c2ecf20Sopenharmony_ciMUX_F(_id, _name, _parent, _reg, _shift, _width, 0, 0) 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_cistruct zx_clk_div { 1188c2ecf20Sopenharmony_ci struct clk_divider div; 1198c2ecf20Sopenharmony_ci u16 id; 1208c2ecf20Sopenharmony_ci}; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci#define DIV_T(_id, _name, _parent, _reg, _shift, _width, _flag, _table) \ 1238c2ecf20Sopenharmony_ci{ \ 1248c2ecf20Sopenharmony_ci .div = { \ 1258c2ecf20Sopenharmony_ci .reg = (void __iomem *) _reg, \ 1268c2ecf20Sopenharmony_ci .shift = _shift, \ 1278c2ecf20Sopenharmony_ci .width = _width, \ 1288c2ecf20Sopenharmony_ci .flags = 0, \ 1298c2ecf20Sopenharmony_ci .table = _table, \ 1308c2ecf20Sopenharmony_ci .lock = &clk_lock, \ 1318c2ecf20Sopenharmony_ci .hw.init = CLK_HW_INIT(_name, \ 1328c2ecf20Sopenharmony_ci _parent, \ 1338c2ecf20Sopenharmony_ci &clk_divider_ops, \ 1348c2ecf20Sopenharmony_ci _flag), \ 1358c2ecf20Sopenharmony_ci }, \ 1368c2ecf20Sopenharmony_ci .id = _id, \ 1378c2ecf20Sopenharmony_ci} 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_cistruct clk_zx_audio_divider { 1408c2ecf20Sopenharmony_ci struct clk_hw hw; 1418c2ecf20Sopenharmony_ci void __iomem *reg_base; 1428c2ecf20Sopenharmony_ci unsigned int rate_count; 1438c2ecf20Sopenharmony_ci spinlock_t *lock; 1448c2ecf20Sopenharmony_ci u16 id; 1458c2ecf20Sopenharmony_ci}; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci#define AUDIO_DIV(_id, _name, _parent, _reg) \ 1488c2ecf20Sopenharmony_ci{ \ 1498c2ecf20Sopenharmony_ci .reg_base = (void __iomem *) _reg, \ 1508c2ecf20Sopenharmony_ci .lock = &clk_lock, \ 1518c2ecf20Sopenharmony_ci .hw.init = CLK_HW_INIT(_name, \ 1528c2ecf20Sopenharmony_ci _parent, \ 1538c2ecf20Sopenharmony_ci &zx_audio_div_ops, \ 1548c2ecf20Sopenharmony_ci 0), \ 1558c2ecf20Sopenharmony_ci .id = _id, \ 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_cistruct clk *clk_register_zx_pll(const char *name, const char *parent_name, 1598c2ecf20Sopenharmony_ci unsigned long flags, void __iomem *reg_base, 1608c2ecf20Sopenharmony_ci const struct zx_pll_config *lookup_table, int count, spinlock_t *lock); 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_cistruct clk_zx_audio { 1638c2ecf20Sopenharmony_ci struct clk_hw hw; 1648c2ecf20Sopenharmony_ci void __iomem *reg_base; 1658c2ecf20Sopenharmony_ci}; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_cistruct clk *clk_register_zx_audio(const char *name, 1688c2ecf20Sopenharmony_ci const char * const parent_name, 1698c2ecf20Sopenharmony_ci unsigned long flags, void __iomem *reg_base); 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ciextern const struct clk_ops zx_pll_ops; 1728c2ecf20Sopenharmony_ciextern const struct clk_ops zx_audio_div_ops; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci#endif 175