18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2018 BayLibre, SAS. 48c2ecf20Sopenharmony_ci * Author: Jerome Brunet <jbrunet@baylibre.com> 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifndef __CLK_REGMAP_H 88c2ecf20Sopenharmony_ci#define __CLK_REGMAP_H 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/clk-provider.h> 118c2ecf20Sopenharmony_ci#include <linux/regmap.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci/** 148c2ecf20Sopenharmony_ci * struct clk_regmap - regmap backed clock 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * @hw: handle between common and hardware-specific interfaces 178c2ecf20Sopenharmony_ci * @map: pointer to the regmap structure controlling the clock 188c2ecf20Sopenharmony_ci * @data: data specific to the clock type 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci * Clock which is controlled by regmap backed registers. The actual type of 218c2ecf20Sopenharmony_ci * of the clock is controlled by the clock_ops and data. 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_cistruct clk_regmap { 248c2ecf20Sopenharmony_ci struct clk_hw hw; 258c2ecf20Sopenharmony_ci struct regmap *map; 268c2ecf20Sopenharmony_ci void *data; 278c2ecf20Sopenharmony_ci}; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistatic inline struct clk_regmap *to_clk_regmap(struct clk_hw *hw) 308c2ecf20Sopenharmony_ci{ 318c2ecf20Sopenharmony_ci return container_of(hw, struct clk_regmap, hw); 328c2ecf20Sopenharmony_ci} 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci/** 358c2ecf20Sopenharmony_ci * struct clk_regmap_gate_data - regmap backed gate specific data 368c2ecf20Sopenharmony_ci * 378c2ecf20Sopenharmony_ci * @offset: offset of the register controlling gate 388c2ecf20Sopenharmony_ci * @bit_idx: single bit controlling gate 398c2ecf20Sopenharmony_ci * @flags: hardware-specific flags 408c2ecf20Sopenharmony_ci * 418c2ecf20Sopenharmony_ci * Flags: 428c2ecf20Sopenharmony_ci * Same as clk_gate except CLK_GATE_HIWORD_MASK which is ignored 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_cistruct clk_regmap_gate_data { 458c2ecf20Sopenharmony_ci unsigned int offset; 468c2ecf20Sopenharmony_ci u8 bit_idx; 478c2ecf20Sopenharmony_ci u8 flags; 488c2ecf20Sopenharmony_ci}; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistatic inline struct clk_regmap_gate_data * 518c2ecf20Sopenharmony_ciclk_get_regmap_gate_data(struct clk_regmap *clk) 528c2ecf20Sopenharmony_ci{ 538c2ecf20Sopenharmony_ci return (struct clk_regmap_gate_data *)clk->data; 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ciextern const struct clk_ops clk_regmap_gate_ops; 578c2ecf20Sopenharmony_ciextern const struct clk_ops clk_regmap_gate_ro_ops; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci/** 608c2ecf20Sopenharmony_ci * struct clk_regmap_div_data - regmap backed adjustable divider specific data 618c2ecf20Sopenharmony_ci * 628c2ecf20Sopenharmony_ci * @offset: offset of the register controlling the divider 638c2ecf20Sopenharmony_ci * @shift: shift to the divider bit field 648c2ecf20Sopenharmony_ci * @width: width of the divider bit field 658c2ecf20Sopenharmony_ci * @table: array of value/divider pairs, last entry should have div = 0 668c2ecf20Sopenharmony_ci * 678c2ecf20Sopenharmony_ci * Flags: 688c2ecf20Sopenharmony_ci * Same as clk_divider except CLK_DIVIDER_HIWORD_MASK which is ignored 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_cistruct clk_regmap_div_data { 718c2ecf20Sopenharmony_ci unsigned int offset; 728c2ecf20Sopenharmony_ci u8 shift; 738c2ecf20Sopenharmony_ci u8 width; 748c2ecf20Sopenharmony_ci u8 flags; 758c2ecf20Sopenharmony_ci const struct clk_div_table *table; 768c2ecf20Sopenharmony_ci}; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_cistatic inline struct clk_regmap_div_data * 798c2ecf20Sopenharmony_ciclk_get_regmap_div_data(struct clk_regmap *clk) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci return (struct clk_regmap_div_data *)clk->data; 828c2ecf20Sopenharmony_ci} 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ciextern const struct clk_ops clk_regmap_divider_ops; 858c2ecf20Sopenharmony_ciextern const struct clk_ops clk_regmap_divider_ro_ops; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci/** 888c2ecf20Sopenharmony_ci * struct clk_regmap_mux_data - regmap backed multiplexer clock specific data 898c2ecf20Sopenharmony_ci * 908c2ecf20Sopenharmony_ci * @hw: handle between common and hardware-specific interfaces 918c2ecf20Sopenharmony_ci * @offset: offset of theregister controlling multiplexer 928c2ecf20Sopenharmony_ci * @table: array of parent indexed register values 938c2ecf20Sopenharmony_ci * @shift: shift to multiplexer bit field 948c2ecf20Sopenharmony_ci * @mask: mask of mutliplexer bit field 958c2ecf20Sopenharmony_ci * @flags: hardware-specific flags 968c2ecf20Sopenharmony_ci * 978c2ecf20Sopenharmony_ci * Flags: 988c2ecf20Sopenharmony_ci * Same as clk_divider except CLK_MUX_HIWORD_MASK which is ignored 998c2ecf20Sopenharmony_ci */ 1008c2ecf20Sopenharmony_cistruct clk_regmap_mux_data { 1018c2ecf20Sopenharmony_ci unsigned int offset; 1028c2ecf20Sopenharmony_ci u32 *table; 1038c2ecf20Sopenharmony_ci u32 mask; 1048c2ecf20Sopenharmony_ci u8 shift; 1058c2ecf20Sopenharmony_ci u8 flags; 1068c2ecf20Sopenharmony_ci}; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistatic inline struct clk_regmap_mux_data * 1098c2ecf20Sopenharmony_ciclk_get_regmap_mux_data(struct clk_regmap *clk) 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci return (struct clk_regmap_mux_data *)clk->data; 1128c2ecf20Sopenharmony_ci} 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ciextern const struct clk_ops clk_regmap_mux_ops; 1158c2ecf20Sopenharmony_ciextern const struct clk_ops clk_regmap_mux_ro_ops; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci#define __MESON_PCLK(_name, _reg, _bit, _ops, _pname) \ 1188c2ecf20Sopenharmony_cistruct clk_regmap _name = { \ 1198c2ecf20Sopenharmony_ci .data = &(struct clk_regmap_gate_data){ \ 1208c2ecf20Sopenharmony_ci .offset = (_reg), \ 1218c2ecf20Sopenharmony_ci .bit_idx = (_bit), \ 1228c2ecf20Sopenharmony_ci }, \ 1238c2ecf20Sopenharmony_ci .hw.init = &(struct clk_init_data) { \ 1248c2ecf20Sopenharmony_ci .name = #_name, \ 1258c2ecf20Sopenharmony_ci .ops = _ops, \ 1268c2ecf20Sopenharmony_ci .parent_hws = (const struct clk_hw *[]) { _pname }, \ 1278c2ecf20Sopenharmony_ci .num_parents = 1, \ 1288c2ecf20Sopenharmony_ci .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ 1298c2ecf20Sopenharmony_ci }, \ 1308c2ecf20Sopenharmony_ci} 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci#define MESON_PCLK(_name, _reg, _bit, _pname) \ 1338c2ecf20Sopenharmony_ci __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ops, _pname) 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci#define MESON_PCLK_RO(_name, _reg, _bit, _pname) \ 1368c2ecf20Sopenharmony_ci __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pname) 1378c2ecf20Sopenharmony_ci#endif /* __CLK_REGMAP_H */ 138