linux/drivers/clk/microchip/clk-mpfs.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * PolarFire SoC MSS/core complex clock control
 *
 * Copyright (C) 2020-2022 Microchip Technology Inc. All rights reserved.
 */
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <dt-bindings/clock/microchip,mpfs-clock.h>
#include <soc/microchip/mpfs.h>

/* address offset of control registers */
#define REG_MSSPLL_REF_CR
#define REG_MSSPLL_POSTDIV01_CR
#define REG_MSSPLL_POSTDIV23_CR
#define REG_MSSPLL_SSCG_2_CR
#define REG_CLOCK_CONFIG_CR
#define REG_RTC_CLOCK_CR
#define REG_SUBBLK_CLOCK_CR
#define REG_SUBBLK_RESET_CR

#define MSSPLL_FBDIV_SHIFT
#define MSSPLL_FBDIV_WIDTH
#define MSSPLL_REFDIV_SHIFT
#define MSSPLL_REFDIV_WIDTH
#define MSSPLL_POSTDIV02_SHIFT
#define MSSPLL_POSTDIV13_SHIFT
#define MSSPLL_POSTDIV_WIDTH
#define MSSPLL_FIXED_DIV

/*
 * This clock ID is defined here, rather than the binding headers, as it is an
 * internal clock only, and therefore has no consumers in other peripheral
 * blocks.
 */
#define CLK_MSSPLL_INTERNAL

struct mpfs_clock_data {};

struct mpfs_msspll_hw_clock {};

#define to_mpfs_msspll_clk(_hw)

struct mpfs_msspll_out_hw_clock {};

#define to_mpfs_msspll_out_clk(_hw)

struct mpfs_cfg_hw_clock {};

struct mpfs_periph_hw_clock {};

/*
 * mpfs_clk_lock prevents anything else from writing to the
 * mpfs clk block while a software locked register is being written.
 */
static DEFINE_SPINLOCK(mpfs_clk_lock);

static const struct clk_parent_data mpfs_ext_ref[] =;

static const struct clk_div_table mpfs_div_cpu_axi_table[] =;

static const struct clk_div_table mpfs_div_ahb_table[] =;

/*
 * The only two supported reference clock frequencies for the PolarFire SoC are
 * 100 and 125 MHz, as the rtc reference is required to be 1 MHz.
 * It therefore only needs to have divider table entries corresponding to
 * divide by 100 and 125.
 */
static const struct clk_div_table mpfs_div_rtcref_table[] =;

/*
 * MSS PLL internal clock
 */

static unsigned long mpfs_clk_msspll_recalc_rate(struct clk_hw *hw, unsigned long prate)
{}

static const struct clk_ops mpfs_clk_msspll_ops =;

#define CLK_PLL(_id, _name, _parent, _shift, _width, _flags, _offset)

static struct mpfs_msspll_hw_clock mpfs_msspll_clks[] =;

static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_clock *msspll_hws,
				     unsigned int num_clks, struct mpfs_clock_data *data)
{}

/*
 * MSS PLL output clocks
 */

#define CLK_PLL_OUT(_id, _name, _parent, _flags, _shift, _width, _offset)

static struct mpfs_msspll_out_hw_clock mpfs_msspll_out_clks[] =;

static int mpfs_clk_register_msspll_outs(struct device *dev,
					 struct mpfs_msspll_out_hw_clock *msspll_out_hws,
					 unsigned int num_clks, struct mpfs_clock_data *data)
{}

/*
 * "CFG" clocks
 */

#define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset)

#define CLK_CPU_OFFSET
#define CLK_AXI_OFFSET
#define CLK_AHB_OFFSET
#define CLK_RTCREF_OFFSET

static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] =;

static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hws,
				  unsigned int num_clks, struct mpfs_clock_data *data)
{}

/*
 * peripheral clocks - devices connected to axi or ahb buses.
 */

#define CLK_PERIPH(_id, _name, _parent, _shift, _flags)

#define PARENT_CLK(PARENT)

/*
 * Critical clocks:
 * - CLK_ENVM: reserved by hart software services (hss) superloop monitor/m mode interrupt
 *   trap handler
 * - CLK_MMUART0: reserved by the hss
 * - CLK_DDRC: provides clock to the ddr subsystem
 * - CLK_RTC: the onboard RTC's AHB bus clock must be kept running as the rtc will stop
 *   if the AHB interface clock is disabled
 * - CLK_FICx: these provide the processor side clocks to the "FIC" (Fabric InterConnect)
 *   clock domain crossers which provide the interface to the FPGA fabric. Disabling them
 *   causes the FPGA fabric to go into reset.
 * - CLK_ATHENA: The athena clock is FIC4, which is reserved for the Athena TeraFire.
 */

static struct mpfs_periph_hw_clock mpfs_periph_clks[] =;

static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_clock *periph_hws,
				     int num_clks, struct mpfs_clock_data *data)
{}

static int mpfs_clk_probe(struct platform_device *pdev)
{}

static const struct of_device_id mpfs_clk_of_match_table[] =;
MODULE_DEVICE_TABLE(of, mpfs_clk_of_match_table);

static struct platform_driver mpfs_clk_driver =;

static int __init clk_mpfs_init(void)
{}
core_initcall(clk_mpfs_init);

static void __exit clk_mpfs_exit(void)
{}
module_exit(clk_mpfs_exit);

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_IMPORT_NS();