162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2017 Chen-Yu Tsai. All rights reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef _CCU_SDM_H 762306a36Sopenharmony_ci#define _CCU_SDM_H 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/clk-provider.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include "ccu_common.h" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_cistruct ccu_sdm_setting { 1462306a36Sopenharmony_ci unsigned long rate; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci /* 1762306a36Sopenharmony_ci * XXX We don't know what the step and bottom register fields 1862306a36Sopenharmony_ci * mean. Just copy the whole register value from the vendor 1962306a36Sopenharmony_ci * kernel for now. 2062306a36Sopenharmony_ci */ 2162306a36Sopenharmony_ci u32 pattern; 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci /* 2462306a36Sopenharmony_ci * M and N factors here should be the values used in 2562306a36Sopenharmony_ci * calculation, not the raw values written to registers 2662306a36Sopenharmony_ci */ 2762306a36Sopenharmony_ci u32 m; 2862306a36Sopenharmony_ci u32 n; 2962306a36Sopenharmony_ci}; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistruct ccu_sdm_internal { 3262306a36Sopenharmony_ci struct ccu_sdm_setting *table; 3362306a36Sopenharmony_ci u32 table_size; 3462306a36Sopenharmony_ci /* early SoCs don't have the SDM enable bit in the PLL register */ 3562306a36Sopenharmony_ci u32 enable; 3662306a36Sopenharmony_ci /* second enable bit in tuning register */ 3762306a36Sopenharmony_ci u32 tuning_enable; 3862306a36Sopenharmony_ci u16 tuning_reg; 3962306a36Sopenharmony_ci}; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci#define _SUNXI_CCU_SDM(_table, _enable, \ 4262306a36Sopenharmony_ci _reg, _reg_enable) \ 4362306a36Sopenharmony_ci { \ 4462306a36Sopenharmony_ci .table = _table, \ 4562306a36Sopenharmony_ci .table_size = ARRAY_SIZE(_table), \ 4662306a36Sopenharmony_ci .enable = _enable, \ 4762306a36Sopenharmony_ci .tuning_enable = _reg_enable, \ 4862306a36Sopenharmony_ci .tuning_reg = _reg, \ 4962306a36Sopenharmony_ci } 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cibool ccu_sdm_helper_is_enabled(struct ccu_common *common, 5262306a36Sopenharmony_ci struct ccu_sdm_internal *sdm); 5362306a36Sopenharmony_civoid ccu_sdm_helper_enable(struct ccu_common *common, 5462306a36Sopenharmony_ci struct ccu_sdm_internal *sdm, 5562306a36Sopenharmony_ci unsigned long rate); 5662306a36Sopenharmony_civoid ccu_sdm_helper_disable(struct ccu_common *common, 5762306a36Sopenharmony_ci struct ccu_sdm_internal *sdm); 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cibool ccu_sdm_helper_has_rate(struct ccu_common *common, 6062306a36Sopenharmony_ci struct ccu_sdm_internal *sdm, 6162306a36Sopenharmony_ci unsigned long rate); 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ciunsigned long ccu_sdm_helper_read_rate(struct ccu_common *common, 6462306a36Sopenharmony_ci struct ccu_sdm_internal *sdm, 6562306a36Sopenharmony_ci u32 m, u32 n); 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ciint ccu_sdm_helper_get_factors(struct ccu_common *common, 6862306a36Sopenharmony_ci struct ccu_sdm_internal *sdm, 6962306a36Sopenharmony_ci unsigned long rate, 7062306a36Sopenharmony_ci unsigned long *m, unsigned long *n); 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci#endif 73