18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2017 Chen-Yu Tsai. All rights reserved. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#ifndef _CCU_SDM_H 78c2ecf20Sopenharmony_ci#define _CCU_SDM_H 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/clk-provider.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include "ccu_common.h" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_cistruct ccu_sdm_setting { 148c2ecf20Sopenharmony_ci unsigned long rate; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci /* 178c2ecf20Sopenharmony_ci * XXX We don't know what the step and bottom register fields 188c2ecf20Sopenharmony_ci * mean. Just copy the whole register value from the vendor 198c2ecf20Sopenharmony_ci * kernel for now. 208c2ecf20Sopenharmony_ci */ 218c2ecf20Sopenharmony_ci u32 pattern; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci /* 248c2ecf20Sopenharmony_ci * M and N factors here should be the values used in 258c2ecf20Sopenharmony_ci * calculation, not the raw values written to registers 268c2ecf20Sopenharmony_ci */ 278c2ecf20Sopenharmony_ci u32 m; 288c2ecf20Sopenharmony_ci u32 n; 298c2ecf20Sopenharmony_ci}; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cistruct ccu_sdm_internal { 328c2ecf20Sopenharmony_ci struct ccu_sdm_setting *table; 338c2ecf20Sopenharmony_ci u32 table_size; 348c2ecf20Sopenharmony_ci /* early SoCs don't have the SDM enable bit in the PLL register */ 358c2ecf20Sopenharmony_ci u32 enable; 368c2ecf20Sopenharmony_ci /* second enable bit in tuning register */ 378c2ecf20Sopenharmony_ci u32 tuning_enable; 388c2ecf20Sopenharmony_ci u16 tuning_reg; 398c2ecf20Sopenharmony_ci}; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci#define _SUNXI_CCU_SDM(_table, _enable, \ 428c2ecf20Sopenharmony_ci _reg, _reg_enable) \ 438c2ecf20Sopenharmony_ci { \ 448c2ecf20Sopenharmony_ci .table = _table, \ 458c2ecf20Sopenharmony_ci .table_size = ARRAY_SIZE(_table), \ 468c2ecf20Sopenharmony_ci .enable = _enable, \ 478c2ecf20Sopenharmony_ci .tuning_enable = _reg_enable, \ 488c2ecf20Sopenharmony_ci .tuning_reg = _reg, \ 498c2ecf20Sopenharmony_ci } 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cibool ccu_sdm_helper_is_enabled(struct ccu_common *common, 528c2ecf20Sopenharmony_ci struct ccu_sdm_internal *sdm); 538c2ecf20Sopenharmony_civoid ccu_sdm_helper_enable(struct ccu_common *common, 548c2ecf20Sopenharmony_ci struct ccu_sdm_internal *sdm, 558c2ecf20Sopenharmony_ci unsigned long rate); 568c2ecf20Sopenharmony_civoid ccu_sdm_helper_disable(struct ccu_common *common, 578c2ecf20Sopenharmony_ci struct ccu_sdm_internal *sdm); 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cibool ccu_sdm_helper_has_rate(struct ccu_common *common, 608c2ecf20Sopenharmony_ci struct ccu_sdm_internal *sdm, 618c2ecf20Sopenharmony_ci unsigned long rate); 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ciunsigned long ccu_sdm_helper_read_rate(struct ccu_common *common, 648c2ecf20Sopenharmony_ci struct ccu_sdm_internal *sdm, 658c2ecf20Sopenharmony_ci u32 m, u32 n); 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ciint ccu_sdm_helper_get_factors(struct ccu_common *common, 688c2ecf20Sopenharmony_ci struct ccu_sdm_internal *sdm, 698c2ecf20Sopenharmony_ci unsigned long rate, 708c2ecf20Sopenharmony_ci unsigned long *m, unsigned long *n); 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci#endif 73