162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2018-2021 SiFive, Inc. 462306a36Sopenharmony_ci * Copyright (C) 2018-2019 Wesley Terpstra 562306a36Sopenharmony_ci * Copyright (C) 2018-2019 Paul Walmsley 662306a36Sopenharmony_ci * Copyright (C) 2020-2021 Zong Li 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * The FU540 PRCI implements clock and reset control for the SiFive 962306a36Sopenharmony_ci * FU540-C000 chip. This driver assumes that it has sole control 1062306a36Sopenharmony_ci * over all PRCI resources. 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * This driver is based on the PRCI driver written by Wesley Terpstra: 1362306a36Sopenharmony_ci * https://github.com/riscv/riscv-linux/commit/999529edf517ed75b56659d456d221b2ee56bb60 1462306a36Sopenharmony_ci * 1562306a36Sopenharmony_ci * References: 1662306a36Sopenharmony_ci * - SiFive FU540-C000 manual v1p0, Chapter 7 "Clocking and Reset" 1762306a36Sopenharmony_ci */ 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#ifndef __SIFIVE_CLK_FU540_PRCI_H 2062306a36Sopenharmony_ci#define __SIFIVE_CLK_FU540_PRCI_H 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#include <linux/module.h> 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#include <dt-bindings/clock/sifive-fu540-prci.h> 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#include "sifive-prci.h" 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* PRCI integration data for each WRPLL instance */ 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic struct __prci_wrpll_data sifive_fu540_prci_corepll_data = { 3262306a36Sopenharmony_ci .cfg0_offs = PRCI_COREPLLCFG0_OFFSET, 3362306a36Sopenharmony_ci .cfg1_offs = PRCI_COREPLLCFG1_OFFSET, 3462306a36Sopenharmony_ci .enable_bypass = sifive_prci_coreclksel_use_hfclk, 3562306a36Sopenharmony_ci .disable_bypass = sifive_prci_coreclksel_use_corepll, 3662306a36Sopenharmony_ci}; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistatic struct __prci_wrpll_data sifive_fu540_prci_ddrpll_data = { 3962306a36Sopenharmony_ci .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET, 4062306a36Sopenharmony_ci .cfg1_offs = PRCI_DDRPLLCFG1_OFFSET, 4162306a36Sopenharmony_ci}; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistatic struct __prci_wrpll_data sifive_fu540_prci_gemgxlpll_data = { 4462306a36Sopenharmony_ci .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET, 4562306a36Sopenharmony_ci .cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET, 4662306a36Sopenharmony_ci}; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci/* Linux clock framework integration */ 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_cistatic const struct clk_ops sifive_fu540_prci_wrpll_clk_ops = { 5162306a36Sopenharmony_ci .set_rate = sifive_prci_wrpll_set_rate, 5262306a36Sopenharmony_ci .round_rate = sifive_prci_wrpll_round_rate, 5362306a36Sopenharmony_ci .recalc_rate = sifive_prci_wrpll_recalc_rate, 5462306a36Sopenharmony_ci .enable = sifive_prci_clock_enable, 5562306a36Sopenharmony_ci .disable = sifive_prci_clock_disable, 5662306a36Sopenharmony_ci .is_enabled = sifive_clk_is_enabled, 5762306a36Sopenharmony_ci}; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistatic const struct clk_ops sifive_fu540_prci_wrpll_ro_clk_ops = { 6062306a36Sopenharmony_ci .recalc_rate = sifive_prci_wrpll_recalc_rate, 6162306a36Sopenharmony_ci}; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistatic const struct clk_ops sifive_fu540_prci_tlclksel_clk_ops = { 6462306a36Sopenharmony_ci .recalc_rate = sifive_prci_tlclksel_recalc_rate, 6562306a36Sopenharmony_ci}; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci/* List of clock controls provided by the PRCI */ 6862306a36Sopenharmony_cistatic struct __prci_clock __prci_init_clocks_fu540[] = { 6962306a36Sopenharmony_ci [FU540_PRCI_CLK_COREPLL] = { 7062306a36Sopenharmony_ci .name = "corepll", 7162306a36Sopenharmony_ci .parent_name = "hfclk", 7262306a36Sopenharmony_ci .ops = &sifive_fu540_prci_wrpll_clk_ops, 7362306a36Sopenharmony_ci .pwd = &sifive_fu540_prci_corepll_data, 7462306a36Sopenharmony_ci }, 7562306a36Sopenharmony_ci [FU540_PRCI_CLK_DDRPLL] = { 7662306a36Sopenharmony_ci .name = "ddrpll", 7762306a36Sopenharmony_ci .parent_name = "hfclk", 7862306a36Sopenharmony_ci .ops = &sifive_fu540_prci_wrpll_ro_clk_ops, 7962306a36Sopenharmony_ci .pwd = &sifive_fu540_prci_ddrpll_data, 8062306a36Sopenharmony_ci }, 8162306a36Sopenharmony_ci [FU540_PRCI_CLK_GEMGXLPLL] = { 8262306a36Sopenharmony_ci .name = "gemgxlpll", 8362306a36Sopenharmony_ci .parent_name = "hfclk", 8462306a36Sopenharmony_ci .ops = &sifive_fu540_prci_wrpll_clk_ops, 8562306a36Sopenharmony_ci .pwd = &sifive_fu540_prci_gemgxlpll_data, 8662306a36Sopenharmony_ci }, 8762306a36Sopenharmony_ci [FU540_PRCI_CLK_TLCLK] = { 8862306a36Sopenharmony_ci .name = "tlclk", 8962306a36Sopenharmony_ci .parent_name = "corepll", 9062306a36Sopenharmony_ci .ops = &sifive_fu540_prci_tlclksel_clk_ops, 9162306a36Sopenharmony_ci }, 9262306a36Sopenharmony_ci}; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cistatic const struct prci_clk_desc prci_clk_fu540 = { 9562306a36Sopenharmony_ci .clks = __prci_init_clocks_fu540, 9662306a36Sopenharmony_ci .num_clks = ARRAY_SIZE(__prci_init_clocks_fu540), 9762306a36Sopenharmony_ci}; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci#endif /* __SIFIVE_CLK_FU540_PRCI_H */ 100