// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2018-2021 SiFive, Inc.
 * Wesley Terpstra
 * Paul Walmsley
 * Zong Li
 * Pragnesh Patel
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * The PRCI implements clock and reset control for the SiFive chip.
 * This driver assumes that it has sole control over all PRCI resources.
 *
 * This driver is based on the PRCI driver written by Wesley Terpstra:
 * https://github.com/riscv/riscv-linux/commit/999529edf517ed75b56659d456d221b2ee56bb60
 */

#include <clk-uclass.h>
#include <clk.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <reset.h>
#include <asm/io.h>
#include <asm/arch/reset.h>
#include <linux/delay.h>
#include <linux/math64.h>
#include <dt-bindings/clock/sifive-fu740-prci.h>

#include "fu540-prci.h"
#include "fu740-prci.h"

/*
 * Private functions
 */

/**
 * __prci_readl() - read from a PRCI register
 * @pd: PRCI context
 * @offs: register offset to read from (in bytes, from PRCI base address)
 *
 * Read the register located at offset @offs from the base virtual
 * address of the PRCI register target described by @pd, and return
 * the value to the caller.
 *
 * Context: Any context.
 *
 * Return: the contents of the register described by @pd and @offs.
 */
static u32 __prci_readl(struct __prci_data *pd, u32 offs)
{
	return readl(pd->va + offs);
}

static void __prci_writel(u32 v, u32 offs, struct __prci_data *pd)
{
	writel(v, pd->va + offs);
}

/* WRPLL-related private functions */

/**
 * __prci_wrpll_unpack() - unpack WRPLL configuration registers into parameters
 * @c: ptr to a struct wrpll_cfg record to write config into
 * @r: value read from the PRCI PLL configuration register
 *
 * Given a value @r read from an FU540 PRCI PLL configuration register,
 * split it into fields and populate it into the WRPLL configuration record
 * pointed to by @c.
 *
 * The COREPLLCFG0 macros are used below, but the other *PLLCFG0 macros
 * have the same register layout.
 *
 * Context: Any context.
 */
static void __prci_wrpll_unpack(struct wrpll_cfg *c, u32 r)
{
	u32 v;

	v = r & PRCI_COREPLLCFG0_DIVR_MASK;
	v >>= PRCI_COREPLLCFG0_DIVR_SHIFT;
	c->divr = v;

	v = r & PRCI_COREPLLCFG0_DIVF_MASK;
	v >>= PRCI_COREPLLCFG0_DIVF_SHIFT;
	c->divf = v;

	v = r & PRCI_COREPLLCFG0_DIVQ_MASK;
	v >>= PRCI_COREPLLCFG0_DIVQ_SHIFT;
	c->divq = v;

	v = r & PRCI_COREPLLCFG0_RANGE_MASK;
	v >>= PRCI_COREPLLCFG0_RANGE_SHIFT;
	c->range = v;

	c->flags &= (WRPLL_FLAGS_INT_FEEDBACK_MASK |
		     WRPLL_FLAGS_EXT_FEEDBACK_MASK);

	/* external feedback mode not supported */
	c->flags |= WRPLL_FLAGS_INT_FEEDBACK_MASK;
}

/**
 * __prci_wrpll_pack() - pack PLL configuration parameters into a register value
 * @c: pointer to a struct wrpll_cfg record containing the PLL's cfg
 *
 * Using a set of WRPLL configuration values pointed to by @c,
 * assemble a PRCI PLL configuration register value, and return it to
 * the caller.
 *
 * Context: Any context.  Caller must ensure that the contents of the
 *          record pointed to by @c do not change during the execution
 *          of this function.
 *
 * Returns: a value suitable for writing into a PRCI PLL configuration
 *          register
 */
static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
{
	u32 r = 0;

	r |= c->divr << PRCI_COREPLLCFG0_DIVR_SHIFT;
	r |= c->divf << PRCI_COREPLLCFG0_DIVF_SHIFT;
	r |= c->divq << PRCI_COREPLLCFG0_DIVQ_SHIFT;
	r |= c->range << PRCI_COREPLLCFG0_RANGE_SHIFT;

	/* external feedback mode not supported */
	r |= PRCI_COREPLLCFG0_FSE_MASK;

	return r;
}

/**
 * __prci_wrpll_read_cfg0() - read the WRPLL configuration from the PRCI
 * @pd: PRCI context
 * @pwd: PRCI WRPLL metadata
 *
 * Read the current configuration of the PLL identified by @pwd from
 * the PRCI identified by @pd, and store it into the local configuration
 * cache in @pwd.
 *
 * Context: Any context.  Caller must prevent the records pointed to by
 *          @pd and @pwd from changing during execution.
 */
static void __prci_wrpll_read_cfg0(struct __prci_data *pd,
				   struct __prci_wrpll_data *pwd)
{
	__prci_wrpll_unpack(&pwd->c, __prci_readl(pd, pwd->cfg0_offs));
}

/**
 * __prci_wrpll_write_cfg0() - write WRPLL configuration into the PRCI
 * @pd: PRCI context
 * @pwd: PRCI WRPLL metadata
 * @c: WRPLL configuration record to write
 *
 * Write the WRPLL configuration described by @c into the WRPLL
 * configuration register identified by @pwd in the PRCI instance
 * described by @c.  Make a cached copy of the WRPLL's current
 * configuration so it can be used by other code.
 *
 * Context: Any context.  Caller must prevent the records pointed to by
 *          @pd and @pwd from changing during execution.
 */
static void __prci_wrpll_write_cfg0(struct __prci_data *pd,
				    struct __prci_wrpll_data *pwd,
				    struct wrpll_cfg *c)
{
	__prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd);

	memcpy(&pwd->c, c, sizeof(*c));
}

/**
 * __prci_wrpll_write_cfg1() - write Clock enable/disable configuration
 * into the PRCI
 * @pd: PRCI context
 * @pwd: PRCI WRPLL metadata
 * @enable: Clock enable or disable value
 */
static void __prci_wrpll_write_cfg1(struct __prci_data *pd,
				    struct __prci_wrpll_data *pwd,
				    u32 enable)
{
	__prci_writel(enable, pwd->cfg1_offs, pd);
}

unsigned long sifive_prci_wrpll_recalc_rate(struct __prci_clock *pc,
					    unsigned long parent_rate)
{
	struct __prci_wrpll_data *pwd = pc->pwd;

	return wrpll_calc_output_rate(&pwd->c, parent_rate);
}

unsigned long sifive_prci_wrpll_round_rate(struct __prci_clock *pc,
					   unsigned long rate,
					   unsigned long *parent_rate)
{
	struct __prci_wrpll_data *pwd = pc->pwd;
	struct wrpll_cfg c;

	memcpy(&c, &pwd->c, sizeof(c));

	wrpll_configure_for_rate(&c, rate, *parent_rate);

	return wrpll_calc_output_rate(&c, *parent_rate);
}

int sifive_prci_wrpll_set_rate(struct __prci_clock *pc,
			       unsigned long rate,
			       unsigned long parent_rate)
{
	struct __prci_wrpll_data *pwd = pc->pwd;
	struct __prci_data *pd = pc->pd;
	int r;

	r = wrpll_configure_for_rate(&pwd->c, rate, parent_rate);
	if (r)
		return r;

	if (pwd->enable_bypass)
		pwd->enable_bypass(pd);

	__prci_wrpll_write_cfg0(pd, pwd, &pwd->c);

	udelay(wrpll_calc_max_lock_us(&pwd->c));

	return 0;
}

int sifive_prci_clock_enable(struct __prci_clock *pc, bool enable)
{
	struct __prci_wrpll_data *pwd = pc->pwd;
	struct __prci_data *pd = pc->pd;

	if (enable) {
		__prci_wrpll_write_cfg1(pd, pwd, PRCI_COREPLLCFG1_CKE_MASK);

		if (pwd->disable_bypass)
			pwd->disable_bypass(pd);

		if (pwd->release_reset)
			pwd->release_reset(pd);
	} else {
		u32 r;

		if (pwd->enable_bypass)
			pwd->enable_bypass(pd);

		r = __prci_readl(pd, pwd->cfg1_offs);
		r &= ~PRCI_COREPLLCFG1_CKE_MASK;

		__prci_wrpll_write_cfg1(pd, pwd, r);
	}

	return 0;
}

/* TLCLKSEL clock integration */

unsigned long sifive_prci_tlclksel_recalc_rate(struct __prci_clock *pc,
					       unsigned long parent_rate)
{
	struct __prci_data *pd = pc->pd;
	u32 v;
	u8 div;

	v = __prci_readl(pd, PRCI_CLKMUXSTATUSREG_OFFSET);
	v &= PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK;
	div = v ? 1 : 2;

	return div_u64(parent_rate, div);
}

/* HFPCLK clock integration */

unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct __prci_clock *pc,
						   unsigned long parent_rate)
{
	struct __prci_data *pd = pc->pd;
	u32 div = __prci_readl(pd, PRCI_HFPCLKPLLDIV_OFFSET);

	return div_u64(parent_rate, div + 2);
}

/**
 * sifive_prci_coreclksel_use_final_corepll() - switch the CORECLK mux to output
 * FINAL_COREPLL
 * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
 *
 * Switch the CORECLK mux to the final COREPLL output clock; return once
 * complete.
 *
 * Context: Any context.  Caller must prevent concurrent changes to the
 *          PRCI_CORECLKSEL_OFFSET register.
 */
void sifive_prci_coreclksel_use_final_corepll(struct __prci_data *pd)
{
	u32 r;

	r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
	r &= ~PRCI_CORECLKSEL_CORECLKSEL_MASK;
	__prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);

	r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);   /* barrier */
}

/**
 * sifive_prci_corepllsel_use_dvfscorepll() - switch the COREPLL mux to
 * output DVFS_COREPLL
 * @pd: struct __prci_data * for the PRCI containing the COREPLL mux reg
 *
 * Switch the COREPLL mux to the DVFSCOREPLL output clock; return once complete.
 *
 * Context: Any context.  Caller must prevent concurrent changes to the
 *          PRCI_COREPLLSEL_OFFSET register.
 */
void sifive_prci_corepllsel_use_dvfscorepll(struct __prci_data *pd)
{
	u32 r;

	r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET);
	r |= PRCI_COREPLLSEL_COREPLLSEL_MASK;
	__prci_writel(r, PRCI_COREPLLSEL_OFFSET, pd);

	r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET);   /* barrier */
}

/**
 * sifive_prci_corepllsel_use_corepll() - switch the COREPLL mux to
 * output COREPLL
 * @pd: struct __prci_data * for the PRCI containing the COREPLL mux reg
 *
 * Switch the COREPLL mux to the COREPLL output clock; return once complete.
 *
 * Context: Any context.  Caller must prevent concurrent changes to the
 *          PRCI_COREPLLSEL_OFFSET register.
 */
void sifive_prci_corepllsel_use_corepll(struct __prci_data *pd)
{
	u32 r;

	r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET);
	r &= ~PRCI_COREPLLSEL_COREPLLSEL_MASK;
	__prci_writel(r, PRCI_COREPLLSEL_OFFSET, pd);

	r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET);   /* barrier */
}

/**
 * sifive_prci_hfpclkpllsel_use_hfclk() - switch the HFPCLKPLL mux to
 * output HFCLK
 * @pd: struct __prci_data * for the PRCI containing the HFPCLKPLL mux reg
 *
 * Switch the HFPCLKPLL mux to the HFCLK input source; return once complete.
 *
 * Context: Any context.  Caller must prevent concurrent changes to the
 *          PRCI_HFPCLKPLLSEL_OFFSET register.
 */
void sifive_prci_hfpclkpllsel_use_hfclk(struct __prci_data *pd)
{
	u32 r;

	r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET);
	r |= PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_MASK;
	__prci_writel(r, PRCI_HFPCLKPLLSEL_OFFSET, pd);

	r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */
}

/**
 * sifive_prci_hfpclkpllsel_use_hfpclkpll() - switch the HFPCLKPLL mux to
 * output HFPCLKPLL
 * @pd: struct __prci_data * for the PRCI containing the HFPCLKPLL mux reg
 *
 * Switch the HFPCLKPLL mux to the HFPCLKPLL output clock; return once complete.
 *
 * Context: Any context.  Caller must prevent concurrent changes to the
 *          PRCI_HFPCLKPLLSEL_OFFSET register.
 */
void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd)
{
	u32 r;

	r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET);
	r &= ~PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_MASK;
	__prci_writel(r, PRCI_HFPCLKPLLSEL_OFFSET, pd);

	r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */
}

static int __prci_consumer_reset(const char *rst_name, bool trigger)
{
	struct udevice *dev;
	struct reset_ctl rst_sig;
	int ret;

	ret = uclass_get_device_by_driver(UCLASS_RESET,
					  DM_DRIVER_GET(sifive_reset),
					  &dev);
	if (ret) {
		dev_err(dev, "Reset driver not found: %d\n", ret);
		return ret;
	}

	ret = reset_get_by_name(dev, rst_name, &rst_sig);
	if (ret) {
		dev_err(dev, "failed to get %s reset\n", rst_name);
		return ret;
	}

	if (reset_valid(&rst_sig)) {
		if (trigger)
			ret = reset_deassert(&rst_sig);
		else
			ret = reset_assert(&rst_sig);
		if (ret) {
			dev_err(dev, "failed to trigger reset id = %ld\n",
				rst_sig.id);
			return ret;
		}
	}

	return ret;
}

/**
 * sifive_prci_ddr_release_reset() - Release DDR reset
 * @pd: struct __prci_data * for the PRCI containing the DDRCLK mux reg
 *
 */
void sifive_prci_ddr_release_reset(struct __prci_data *pd)
{
	/* Release DDR ctrl reset */
	__prci_consumer_reset("ddr_ctrl", true);

	/* HACK to get the '1 full controller clock cycle'. */
	asm volatile ("fence");

	/* Release DDR AXI reset */
	__prci_consumer_reset("ddr_axi", true);

	/* Release DDR AHB reset */
	__prci_consumer_reset("ddr_ahb", true);

	/* Release DDR PHY reset */
	__prci_consumer_reset("ddr_phy", true);

	/* HACK to get the '1 full controller clock cycle'. */
	asm volatile ("fence");

	/*
	 * These take like 16 cycles to actually propagate. We can't go sending
	 * stuff before they come out of reset. So wait.
	 */
	for (int i = 0; i < 256; i++)
		asm volatile ("nop");
}

/**
 * sifive_prci_ethernet_release_reset() - Release ethernet reset
 * @pd: struct __prci_data * for the PRCI containing the Ethernet CLK mux reg
 *
 */
void sifive_prci_ethernet_release_reset(struct __prci_data *pd)
{
	/* Release GEMGXL reset */
	__prci_consumer_reset("gemgxl_reset", true);

	/* Procmon => core clock */
	__prci_writel(PRCI_PROCMONCFG_CORE_CLOCK_MASK, PRCI_PROCMONCFG_OFFSET,
		      pd);

	/* Release Chiplink reset */
	__prci_consumer_reset("cltx_reset", true);
}

/**
 * sifive_prci_cltx_release_reset() - Release cltx reset
 * @pd: struct __prci_data * for the PRCI containing the Ethernet CLK mux reg
 *
 */
void sifive_prci_cltx_release_reset(struct __prci_data *pd)
{
	/* Release CLTX reset */
	__prci_consumer_reset("cltx_reset", true);
}

/* Core clock mux control */

/**
 * sifive_prci_coreclksel_use_hfclk() - switch the CORECLK mux to output HFCLK
 * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
 *
 * Switch the CORECLK mux to the HFCLK input source; return once complete.
 *
 * Context: Any context.  Caller must prevent concurrent changes to the
 *          PRCI_CORECLKSEL_OFFSET register.
 */
void sifive_prci_coreclksel_use_hfclk(struct __prci_data *pd)
{
	u32 r;

	r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
	r |= PRCI_CORECLKSEL_CORECLKSEL_MASK;
	__prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);

	r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */
}

/**
 * sifive_prci_coreclksel_use_corepll() - switch the CORECLK mux to output COREPLL
 * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
 *
 * Switch the CORECLK mux to the PLL output clock; return once complete.
 *
 * Context: Any context.  Caller must prevent concurrent changes to the
 *          PRCI_CORECLKSEL_OFFSET register.
 */
void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd)
{
	u32 r;

	r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
	r &= ~PRCI_CORECLKSEL_CORECLKSEL_MASK;
	__prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);

	r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */
}

static ulong sifive_prci_parent_rate(struct __prci_clock *pc, struct prci_clk_desc *data)
{
	ulong parent_rate;
	ulong i;
	struct __prci_clock *p;

	if (strcmp(pc->parent_name, "corepll") == 0 ||
	    strcmp(pc->parent_name, "hfpclkpll") == 0) {
		for (i = 0; i < data->num_clks; i++) {
			if (strcmp(pc->parent_name, data->clks[i].name) == 0)
				break;
		}

		if (i >= data->num_clks)
			return -ENXIO;

		p = &data->clks[i];
		if (!p->pd || !p->ops->recalc_rate)
			return -ENXIO;

		return p->ops->recalc_rate(p, sifive_prci_parent_rate(p, data));
	}

	if (strcmp(pc->parent_name, "rtcclk") == 0)
		parent_rate = clk_get_rate(&pc->pd->parent_rtcclk);
	else
		parent_rate = clk_get_rate(&pc->pd->parent_hfclk);

	return parent_rate;
}

static ulong sifive_prci_get_rate(struct clk *clk)
{
	struct __prci_clock *pc;
	struct prci_clk_desc *data =
		(struct prci_clk_desc *)dev_get_driver_data(clk->dev);

	if (data->num_clks <= clk->id)
		return -ENXIO;

	pc = &data->clks[clk->id];
	if (!pc->pd || !pc->ops->recalc_rate)
		return -ENXIO;

	return pc->ops->recalc_rate(pc, sifive_prci_parent_rate(pc, data));
}

static ulong sifive_prci_set_rate(struct clk *clk, ulong rate)
{
	int err;
	struct __prci_clock *pc;
	struct prci_clk_desc *data =
		(struct prci_clk_desc *)dev_get_driver_data(clk->dev);

	if (data->num_clks <= clk->id)
		return -ENXIO;

	pc = &data->clks[clk->id];
	if (!pc->pd || !pc->ops->set_rate)
		return -ENXIO;

	err = pc->ops->set_rate(pc, rate, sifive_prci_parent_rate(pc, data));
	if (err)
		return err;

	return rate;
}

static int sifive_prci_enable(struct clk *clk)
{
	struct __prci_clock *pc;
	int ret = 0;
	struct prci_clk_desc *data =
		(struct prci_clk_desc *)dev_get_driver_data(clk->dev);

	if (data->num_clks <= clk->id)
		return -ENXIO;

	pc = &data->clks[clk->id];
	if (!pc->pd)
		return -ENXIO;

	if (pc->ops->enable_clk)
		ret = pc->ops->enable_clk(pc, 1);

	return ret;
}

static int sifive_prci_disable(struct clk *clk)
{
	struct __prci_clock *pc;
	int ret = 0;
	struct prci_clk_desc *data =
		(struct prci_clk_desc *)dev_get_driver_data(clk->dev);

	if (data->num_clks <= clk->id)
		return -ENXIO;

	pc = &data->clks[clk->id];
	if (!pc->pd)
		return -ENXIO;

	if (pc->ops->enable_clk)
		ret = pc->ops->enable_clk(pc, 0);

	return ret;
}

static int sifive_prci_probe(struct udevice *dev)
{
	int i, err;
	struct __prci_clock *pc;
	struct __prci_data *pd = dev_get_priv(dev);

	struct prci_clk_desc *data =
		(struct prci_clk_desc *)dev_get_driver_data(dev);

	pd->va = dev_read_addr_ptr(dev);
	if (!pd->va)
		return -EINVAL;

	err = clk_get_by_index(dev, 0, &pd->parent_hfclk);
	if (err)
		return err;

	err = clk_get_by_index(dev, 1, &pd->parent_rtcclk);
	if (err)
		return err;

	for (i = 0; i < data->num_clks; ++i) {
		pc = &data->clks[i];
		pc->pd = pd;
		if (pc->pwd)
			__prci_wrpll_read_cfg0(pd, pc->pwd);
	}

	if (IS_ENABLED(CONFIG_SPL_BUILD)) {
		if (device_is_compatible(dev, "sifive,fu740-c000-prci")) {
			u32 prci_pll_reg;
			unsigned long parent_rate;

			prci_pll_reg = readl(pd->va + PRCI_PRCIPLL_OFFSET);

			if (prci_pll_reg & PRCI_PRCIPLL_HFPCLKPLL) {
				/*
				 * Only initialize the HFPCLK PLL. In this
				 * case the design uses hfpclk to drive
				 * Chiplink
				 */
				pc = &data->clks[FU740_PRCI_CLK_HFPCLKPLL];
				parent_rate = sifive_prci_parent_rate(pc, data);
				sifive_prci_wrpll_set_rate(pc, 260000000,
							   parent_rate);
				pc->ops->enable_clk(pc, 1);
			} else if (prci_pll_reg & PRCI_PRCIPLL_CLTXPLL) {
				/* CLTX pll init */
				pc = &data->clks[FU740_PRCI_CLK_CLTXPLL];
				parent_rate = sifive_prci_parent_rate(pc, data);
				sifive_prci_wrpll_set_rate(pc, 260000000,
							   parent_rate);
				pc->ops->enable_clk(pc, 1);
			}
		}
	}

	return 0;
}

static struct clk_ops sifive_prci_ops = {
	.set_rate = sifive_prci_set_rate,
	.get_rate = sifive_prci_get_rate,
	.enable = sifive_prci_enable,
	.disable = sifive_prci_disable,
};

static int sifive_clk_bind(struct udevice *dev)
{
	return sifive_reset_bind(dev, PRCI_DEVICERESETCNT);
}

static const struct udevice_id sifive_prci_ids[] = {
	{ .compatible = "sifive,fu540-c000-prci", .data = (ulong)&prci_clk_fu540 },
	{ .compatible = "sifive,fu740-c000-prci", .data = (ulong)&prci_clk_fu740 },
	{ }
};

U_BOOT_DRIVER(sifive_prci) = {
	.name = "sifive-prci",
	.id = UCLASS_CLK,
	.of_match = sifive_prci_ids,
	.probe = sifive_prci_probe,
	.ops = &sifive_prci_ops,
	.priv_auto = sizeof(struct __prci_data),
	.bind = sifive_clk_bind,
};
